({
setPartsOrderContext: (context) =>
@@ -295,11 +296,11 @@ export function BillsListPage({
pagination={
search?.search
? {
- pageSize: 25,
+ pageSize: pageLimit,
showSizeChanger: false,
}
: {
- pageSize: 25,
+ pageSize: pageLimit,
current: parseInt(page || 1),
total: total,
showSizeChanger: false,
diff --git a/client/src/pages/bills/bills.page.container.jsx b/client/src/pages/bills/bills.page.container.jsx
index 22a8b61b9..40e662899 100644
--- a/client/src/pages/bills/bills.page.container.jsx
+++ b/client/src/pages/bills/bills.page.container.jsx
@@ -13,6 +13,7 @@ import {
setSelectedHeader,
} from "../../redux/application/application.actions";
import BillsPageComponent from "./bills.page.component";
+import {pageLimit} from "../../utils/config";
const mapDispatchToProps = (dispatch) => ({
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
@@ -38,8 +39,8 @@ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
order: [
searchObj
? JSON.parse(searchObj)
diff --git a/client/src/pages/contracts/contracts.page.container.jsx b/client/src/pages/contracts/contracts.page.container.jsx
index c4f4fef7b..466b468e0 100644
--- a/client/src/pages/contracts/contracts.page.container.jsx
+++ b/client/src/pages/contracts/contracts.page.container.jsx
@@ -12,6 +12,7 @@ import {
setSelectedHeader,
} from "../../redux/application/application.actions";
import ContractsPageComponent from "./contracts.page.component";
+import {pageLimit} from "../../utils/config";
const mapDispatchToProps = (dispatch) => ({
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
@@ -29,8 +30,8 @@ export function ContractsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
nextFetchPolicy: "network-only",
variables: {
search: search || "",
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
order: [
{
[sortcolumn || "start"]: sortorder
diff --git a/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx b/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx
index e41e80f40..93bffe97f 100644
--- a/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx
+++ b/client/src/pages/courtesy-car-detail/courtesy-car-detail.page.container.jsx
@@ -19,6 +19,7 @@ import NotFound from "../../components/not-found/not-found.component";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
import queryString from "query-string";
import { useLocation } from "react-router-dom";
+import {pageLimit} from "../../utils/config";
const mapDispatchToProps = (dispatch) => ({
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
@@ -41,8 +42,8 @@ export function CourtesyCarDetailPageContainer({
const { loading, error, data } = useQuery(QUERY_CC_BY_PK, {
variables: {
id: ccId,
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
order: [
{
[sortcolumn || "start"]: sortorder
diff --git a/client/src/pages/export-logs/export-logs.page.component.jsx b/client/src/pages/export-logs/export-logs.page.component.jsx
index 0b4dcd634..7ae8977cf 100644
--- a/client/src/pages/export-logs/export-logs.page.component.jsx
+++ b/client/src/pages/export-logs/export-logs.page.component.jsx
@@ -12,6 +12,7 @@ import AlertComponent from "../../components/alert/alert.component";
import { QUERY_EXPORT_LOG_PAGINATED } from "../../graphql/accounting.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { DateTimeFormatter } from "../../utils/DateFormatter";
+import {pageLimit} from "../../utils/config";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -29,8 +30,8 @@ export function ExportLogsPageComponent({ bodyshop }) {
nextFetchPolicy: "network-only",
variables: {
search: search || "",
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
order: [
{
[sortcolumn || "created_at"]: sortorder
@@ -178,7 +179,7 @@ export function ExportLogsPageComponent({ bodyshop }) {
loading={loading}
pagination={{
position: "top",
- pageSize: 25,
+ pageSize: pageLimit,
current: parseInt(page || 1),
total: data && data.search_exportlog_aggregate.aggregate.count,
}}
diff --git a/client/src/pages/jobs-all/jobs-all.container.jsx b/client/src/pages/jobs-all/jobs-all.container.jsx
index 2518d6c16..b9fa9a52a 100644
--- a/client/src/pages/jobs-all/jobs-all.container.jsx
+++ b/client/src/pages/jobs-all/jobs-all.container.jsx
@@ -13,6 +13,7 @@ import {
setBreadcrumbs,
setSelectedHeader,
} from "../../redux/application/application.actions";
+import {pageLimit} from "../../utils/config";
const mapStateToProps = createStructuredSelector({
//bodyshop: selectBodyshop,
@@ -33,16 +34,16 @@ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
...(statusFilters ? { statusList: JSON.parse(statusFilters) } : {}),
order: [
{
[sortcolumn || "ro_number"]:
sortorder && sortorder !== "false"
- ? sortorder === "descend"
+ ? (sortorder === "descend"
? "desc"
- : "asc"
+ : "asc")
: "desc",
},
],
diff --git a/client/src/pages/parts-queue/parts-queue.page.component.jsx b/client/src/pages/parts-queue/parts-queue.page.component.jsx
index 5d6226bdb..62970d788 100644
--- a/client/src/pages/parts-queue/parts-queue.page.component.jsx
+++ b/client/src/pages/parts-queue/parts-queue.page.component.jsx
@@ -18,6 +18,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
import { DateTimeFormatter, TimeAgoFormatter } from "../../utils/DateFormatter";
import { alphaSort, dateSort } from "../../utils/sorters";
import useLocalStorage from "../../utils/useLocalStorage";
+import {pageLimit} from "../../utils/config";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -296,7 +297,7 @@ export function PartsQueuePageComponent({ bodyshop }) {
loading={loading}
pagination={{
position: "top",
- pageSize: 50,
+ pageSize: pageLimit,
// current: parseInt(page || 1),
// total: data && data.jobs_aggregate.aggregate.count,
}}
diff --git a/client/src/pages/payments-all/payments-all.container.page.jsx b/client/src/pages/payments-all/payments-all.container.page.jsx
index 07547bc2e..3d3cb6287 100644
--- a/client/src/pages/payments-all/payments-all.container.page.jsx
+++ b/client/src/pages/payments-all/payments-all.container.page.jsx
@@ -14,6 +14,7 @@ import {
setSelectedHeader,
} from "../../redux/application/application.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
+import {pageLimit} from "../../utils/config";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -34,8 +35,8 @@ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
order: [
searchObj
? JSON.parse(searchObj)
diff --git a/client/src/pages/phonebook/phonebook.page.component.jsx b/client/src/pages/phonebook/phonebook.page.component.jsx
index 9a7a13777..5ce863444 100644
--- a/client/src/pages/phonebook/phonebook.page.component.jsx
+++ b/client/src/pages/phonebook/phonebook.page.component.jsx
@@ -17,6 +17,7 @@ import {
import ChatOpenButton from "../../components/chat-open-button/chat-open-button.component";
import { alphaSort } from "../../utils/sorters";
import { HasRbacAccess } from "../../components/rbac-wrapper/rbac-wrapper.component";
+import {pageLimit} from "../../utils/config";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -35,8 +36,8 @@ export function PhonebookPageComponent({ bodyshop, authLevel }) {
nextFetchPolicy: "network-only",
variables: {
search: search || "",
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
order: [
{
[sortcolumn || "lastname"]: sortorder
@@ -189,7 +190,7 @@ export function PhonebookPageComponent({ bodyshop, authLevel }) {
loading={loading}
pagination={{
position: "top",
- pageSize: 25,
+ pageSize: pageLimit,
current: parseInt(page || 1),
total: data && data.search_phonebook_aggregate.aggregate.count,
}}
diff --git a/client/src/pages/shop-csi/shop-csi.container.page.jsx b/client/src/pages/shop-csi/shop-csi.container.page.jsx
index 132ee7999..f0c295685 100644
--- a/client/src/pages/shop-csi/shop-csi.container.page.jsx
+++ b/client/src/pages/shop-csi/shop-csi.container.page.jsx
@@ -16,6 +16,7 @@ import {
} from "../../redux/application/application.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
+import {pageLimit} from "../../utils/config";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
@@ -42,8 +43,8 @@ export function ShopCsiContainer({
nextFetchPolicy: "network-only",
variables: {
//search: search || "",
- offset: page ? (page - 1) * 25 : 0,
- limit: 25,
+ offset: page ? (page - 1) * pageLimit : 0,
+ limit: pageLimit,
order: [
{
[sortcolumn || "completedon"]: sortorder
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 27f804663..bbac4cc7b 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -56,13 +56,13 @@
"history": "History",
"inproduction": "Jobs In Production",
"manualevent": "Add Manual Appointment",
- "noarrivingjobs": "No jobs are arriving.",
- "nocompletingjobs": "No jobs scheduled for completion.",
+ "noarrivingjobs": "No Jobs are arriving.",
+ "nocompletingjobs": "No Jobs scheduled for completion.",
"nodateselected": "No date has been selected.",
"priorappointments": "Previous Appointments",
"reminder": "This is {{shopname}} reminding you about an appointment on {{date}} at {{time}}. Please let us know if you are not able to make the appointment. We look forward to seeing you soon. ",
"scheduledfor": "Scheduled appointment for: ",
- "severalerrorsfound": "Several jobs have issues which may prevent accurate smart scheduling. Click to expand.",
+ "severalerrorsfound": "Several Jobs have issues which may prevent accurate smart scheduling. Click to expand.",
"smartscheduling": "Smart Scheduling",
"suggesteddates": "Suggested Dates"
},
@@ -117,11 +117,11 @@
"jobinproductionchange": "Job production status set to {{inproduction}}",
"jobioucreated": "IOU Created.",
"jobmodifylbradj": "Labor adjustments modified {{mod_lbr_ty}} / {{hours}}.",
- "jobnoteadded": "Note added to job.",
- "jobnotedeleted": "Note deleted from job.",
- "jobnoteupdated": "Note updated on job.",
- "jobspartsorder": "Parts order {{order_number}} added to job.",
- "jobspartsreturn": "Parts return {{order_number}} added to job.",
+ "jobnoteadded": "Note added to Job.",
+ "jobnotedeleted": "Note deleted from Job.",
+ "jobnoteupdated": "Note updated on Job.",
+ "jobspartsorder": "Parts order {{order_number}} added to Job.",
+ "jobspartsreturn": "Parts return {{order_number}} added to Job.",
"jobstatuschange": "Job status changed to {{status}}.",
"jobsupplement": "Job supplement imported."
}
@@ -210,7 +210,7 @@
"markforreexport": "Mark for Re-export",
"new": "New Bill",
"noneselected": "No bill selected.",
- "onlycmforinvoiced": "Only credit memos can be entered for any job that has been invoiced, exported, or voided.",
+ "onlycmforinvoiced": "Only credit memos can be entered for any Job that has been invoiced, exported, or voided.",
"retailtotal": "Bills Retail Total",
"savewithdiscrepancy": "You are about to save this bill with a discrepancy. The system will continue to use the calculated amount using the bill lines. Press cancel to return to the bill.",
"state_tax": "Provincial/State Tax",
@@ -658,7 +658,7 @@
"printall": "Print All Documents"
},
"errors": {
- "complete": "Error during job checklist completion. {{error}}",
+ "complete": "Error during Job checklist completion. {{error}}",
"nochecklist": "No checklist has been configured for your shop. "
},
"labels": {
@@ -666,7 +666,7 @@
"allow_text_message": "Permission to Text?",
"checklist": "Checklist",
"printpack": "Job Intake Print Pack",
- "removefromproduction": "Remove job from production?"
+ "removefromproduction": "Remove Job from Production?"
},
"successes": {
"completed": "Job checklist completed."
@@ -682,9 +682,9 @@
"senddltoform": "Insert Driver's License Information"
},
"errors": {
- "fetchingjobinfo": "Error fetching job info. {{error}}.",
- "returning": "Error returning courtesy car. {{error}}",
- "saving": "Error saving contract. {{error}}",
+ "fetchingjobinfo": "Error fetching Job Info. {{error}}.",
+ "returning": "Error returning Courtesy Car. {{error}}",
+ "saving": "Error saving Contract. {{error}}",
"selectjobandcar": "Please ensure both a car and job are selected."
},
"fields": {
@@ -741,7 +741,7 @@
"driverinformation": "Driver's Information",
"findcontract": "Find Contract",
"findermodal": "Contract Finder",
- "noteconvertedfrom": "R.O. created from converted Courtesy Car Contract {{agreementnumber}}.",
+ "noteconvertedfrom": "R.O. created from converted Courtesy Car Contract {{agreementnumber}}.",
"populatefromjob": "Populate from Job",
"rates": "Contract Rates",
"time": "Time",
@@ -763,7 +763,7 @@
"return": "Return Car"
},
"errors": {
- "saving": "Error saving courtesy card. {{error}}"
+ "saving": "Error saving Courtesy Car. {{error}}"
},
"fields": {
"color": "Color",
@@ -914,7 +914,7 @@
"upload_limitexceeded": "Uploading all selected documents will exceed the job storage limit for your shop. ",
"upload_limitexceeded_title": "Unable to upload document(s)",
"uploading": "Uploading...",
- "usage": "of job storage used. ({{used}} / {{total}})"
+ "usage": "of Job storage used. ({{used}} / {{total}})"
},
"successes": {
"delete": "Document(s) deleted successfully.",
@@ -1375,28 +1375,28 @@
},
"errors": {
"addingtoproduction": "Error adding to production. {{error}}",
- "cannotintake": "Intake cannot be completed for this job. It has either already been completed or the job is already here.",
- "closing": "Error closing job. {{error}}",
- "creating": "Error encountered while creating job. {{error}}",
- "deleted": "Error deleting job. {{error}}",
- "exporting": "Error exporting job. {{error}}",
+ "cannotintake": "Intake cannot be completed for this Job. It has either already been completed or the Job is already here.",
+ "closing": "Error closing Job. {{error}}",
+ "creating": "Error encountered while creating Job. {{error}}",
+ "deleted": "Error deleting Job. {{error}}",
+ "exporting": "Error exporting Job. {{error}}",
"exporting-partner": "Unable to connect to ImEX Partner. Please ensure it is running and logged in.",
- "invoicing": "Error invoicing job. {{error}}",
- "noaccess": "This job does not exist or you do not have access to it.",
+ "invoicing": "Error invoicing Job. {{error}}",
+ "noaccess": "This Job does not exist or you do not have access to it.",
"nodamage": "No damage points on estimate.",
- "nodates": "No dates specified for this job.",
+ "nodates": "No dates specified for this Job.",
"nofinancial": "No financial data has been calculated yet for this job. Please save it again.",
- "nojobselected": "No job is selected.",
+ "nojobselected": "No Job is selected.",
"noowner": "No owner associated.",
"novehicle": "No vehicle associated.",
"partspricechange": "",
"saving": "Error encountered while saving record.",
- "scanimport": "Error importing job. {{message}}",
- "totalscalc": "Error while calculating new job totals.",
- "updating": "Error while updating job(s). {{error}}",
+ "scanimport": "Error importing Job. {{message}}",
+ "totalscalc": "Error while calculating new Job totals.",
+ "updating": "Error while updating Job(s). {{error}}",
"validation": "Please ensure all fields are entered correctly.",
"validationtitle": "Validation Error",
- "voiding": "Error voiding job. {{error}}"
+ "voiding": "Error voiding Job. {{error}}"
},
"fields": {
"actual_completion": "Actual Completion",
@@ -1673,9 +1673,9 @@
"adminwarning": "Use the functionality on this page at your own risk. You are responsible for any and all changes to your data.",
"allocations": "Allocations",
"alreadyaddedtoscoreboard": "Job has already been added to scoreboard. Saving will update the previous entry.",
- "alreadyclosed": "This job has already been closed.",
+ "alreadyclosed": "This Job has already been closed.",
"appointmentconfirmation": "Send confirmation to customer?",
- "associationwarning": "Any changes to associations will require updating the data from the new parent record to the job.",
+ "associationwarning": "Any changes to associations will require updating the data from the new parent record to the Job.",
"audit": "Audit Trail",
"available": "Available",
"availablejobs": "Available Jobs",
@@ -1683,7 +1683,7 @@
"days": "Days",
"rate": "PVRT Rate"
},
- "ca_gst_all_if_null": "If the job is marked as a \"GST Registrant\" and this value is set to $0, the customer will be responsible for paying all of the GST by default. ",
+ "ca_gst_all_if_null": "If the Job is marked as a \"GST Registrant\" and this value is set to $0, the customer will be responsible for paying all of the GST by default. ",
"calc_repair_days": "Calculated Repair Days",
"calc_repair_days_tt": "This is the approximate number of days required to complete the repair according to the target touch time in your shop configuration (current set to {{target_touchtime}}).",
"cards": {
@@ -1699,7 +1699,7 @@
"totals": "Totals",
"vehicle": "Vehicle"
},
- "changeclass": "Changing the job's class can have fundamental impacts to already exported accounting items. Are you sure you want to do this?",
+ "changeclass": "Changing the Job's class can have fundamental impacts to already exported accounting items. Are you sure you want to do this?",
"checklistcompletedby": "Checklist completed by {{by}} at {{at}}",
"checklistdocuments": "Checklist Documents",
"checklists": "Checklists",
@@ -1723,12 +1723,12 @@
"vehicleinfo": "Vehicle Info"
},
"createiouwarning": "Are you sure you want to create an IOU for these lines? A new RO will be created based on those lines for this customer.",
- "creating_new_job": "Creating new job...",
+ "creating_new_job": "Creating new Job...",
"deductible": {
"stands": "Stands",
"waived": "Waived"
},
- "deleteconfirm": "Are you sure you want to delete this job? This cannot be undone. ",
+ "deleteconfirm": "Are you sure you want to delete this Job? This cannot be undone. ",
"deletedelivery": "Delete Delivery Checklist",
"deleteintake": "Delete Intake Checklist",
"deliverchecklist": "Deliver Checklist",
@@ -1749,7 +1749,7 @@
"documents": "Documents",
"documents-images": "Images",
"documents-other": "Other Documents",
- "duplicateconfirm": "Are you sure you want to duplicate this job? Some elements of this job will not be duplicated.",
+ "duplicateconfirm": "Are you sure you want to duplicate this Job? Some elements of this Job will not be duplicated.",
"emailaudit": "Email Audit Trail",
"employeeassignments": "Employee Assignments",
"estimatelines": "Estimate Lines",
@@ -1760,7 +1760,7 @@
"gppercent": "% G.P.",
"hrs_claimed": "Hours Claimed",
"hrs_total": "Hours Total",
- "importnote": "The job was initially imported.",
+ "importnote": "The Job was initially imported.",
"inproduction": "In Production",
"intakechecklist": "Intake Checklist",
"iou": "IOU",
@@ -1793,9 +1793,9 @@
"calculatedcreditsnotreceived": "The calculated credits not received is derived by subtracting the amount of credit memos entered from the retail total of returns created. This does not take into account whether the credit was marked as received. You can find more information here.",
"creditmemos": "The total retail amount of all returns created. This amount does not reflect credit memos that have been posted.",
"creditsnotreceived": "This total reflects the total retail of parts returns lines that have not been explicitly marked as returned when posting a credit memo. You can learn more about this here here. ",
- "discrep1": "If the discrepancy is not $0, you may have one of the following:
\n\n
\n
Too many bills/bill lines that have been posted against this RO. Check to make sure every bill posted on this RO is correctly posted and assigned.
\n
You do not have the latest supplement imported, or, a supplement must be submitted and then imported.
\n
You have posted a bill line to labor.
\n
\n \nThere may be additional issues not listed above that prevent this job from reconciling.",
- "discrep2": "If the discrepancy is not $0, you may have one of the following:
\n\n
\n
Used an incorrect rate when deducting from labor.
\n
An outstanding imbalance higher in the reconciliation process.
\n
\n \nThere may be additional issues not listed above that prevent this job from reconciling.",
- "discrep3": "If the discrepancy is not $0, you may have one of the following:
\n\n
\n
A parts order return has not been created.
\n
An outstanding imbalance higher in the reconciliation process.
\n
\n \nThere may be additional issues not listed above that prevent this job from reconciling.",
+ "discrep1": "If the discrepancy is not $0, you may have one of the following:
\n\n
\n
Too many bills/bill lines that have been posted against this RO. Check to make sure every bill posted on this RO is correctly posted and assigned.
\n
You do not have the latest supplement imported, or, a supplement must be submitted and then imported.
\n
You have posted a bill line to labor.
\n
\n \nThere may be additional issues not listed above that prevent this Job from reconciling.",
+ "discrep2": "If the discrepancy is not $0, you may have one of the following:
\n\n
\n
Used an incorrect rate when deducting from labor.
\n
An outstanding imbalance higher in the reconciliation process.
\n
\n \nThere may be additional issues not listed above that prevent this Job from reconciling.",
+ "discrep3": "If the discrepancy is not $0, you may have one of the following:
\n\n
\n
A parts order return has not been created.
\n
An outstanding imbalance higher in the reconciliation process.
\n
\n \nThere may be additional issues not listed above that prevent this Job from reconciling.",
"laboradj": "The sum of all bill lines that deducted from labor hours, rather than part prices.",
"partstotal": "This is the total of all parts and sublet amounts on the vehicle (some of these may require an in-house invoice). \nItems such as shop and paint materials, labor online lines, etc. are not included in this total.",
"totalreturns": "The total retail amount of returns created for this job."
@@ -1826,13 +1826,13 @@
"sale_parts": "Sales - Parts",
"sale_sublet": "Sales - Sublet",
"sales": "Sales",
- "savebeforeconversion": "You have unsaved changes on the job. Please save them before converting it. ",
- "scheduledinchange": "The scheduled in is based off the latest appointment. To change this date, please schedule or reschedule the job. ",
+ "savebeforeconversion": "You have unsaved changes on the Job. Please save them before converting it. ",
+ "scheduledinchange": "The scheduled in is based off the latest appointment. To change this date, please schedule or reschedule the Job. ",
"specialcoveragepolicy": "Special Coverage Policy Applies",
"state_tax_amt": "Provincial/State Taxes",
"subletstotal": "Sublets Total",
"subtotal": "Subtotal",
- "supplementnote": "The job had a supplement imported.",
+ "supplementnote": "The Job had a supplement imported.",
"suspended": "SUSPENDED",
"suspense": "Suspense",
"threshhold": "Max Threshold: ${{amount}}",
@@ -1841,16 +1841,16 @@
"total_repairs": "Total Repairs",
"total_sales": "Total Sales",
"totals": "Totals",
- "unvoidnote": "This job was unvoided.",
+ "unvoidnote": "This Job was unvoided.",
"vehicle_info": "Vehicle",
"vehicleassociation": "Vehicle Association",
"viewallocations": "View Allocations",
- "voidjob": "Are you sure you want to void this job? This cannot be easily undone. ",
- "voidnote": "This job was voided."
+ "voidjob": "Are you sure you want to void this Job? This cannot be easily undone. ",
+ "voidnote": "This Job was voided."
},
"successes": {
"addedtoproduction": "Job added to production board.",
- "all_deleted": "{{count}} jobs deleted successfully.",
+ "all_deleted": "{{count}} Jobs deleted successfully.",
"closed": "Job closed successfully.",
"converted": "Job converted successfully.",
"created": "Job created successfully. Click to view.",
@@ -2026,7 +2026,7 @@
},
"errors": {
"invalidphone": "The phone number is invalid. Unable to open conversation. ",
- "noattachedjobs": "No jobs have been associated to this conversation. ",
+ "noattachedjobs": "No Jobs have been associated to this conversation. ",
"updatinglabel": "Error updating label. {{error}}"
},
"labels": {
@@ -2035,7 +2035,7 @@
"maxtenimages": "You can only select up to a maximum of 10 images at a time.",
"messaging": "Messaging",
"noallowtxt": "This customer has not indicated their permission to be messaged.",
- "nojobs": "Not associated to any job.",
+ "nojobs": "Not associated to any Job.",
"nopush": "Polling Mode Enabled",
"phonenumber": "Phone #",
"presets": "Presets",
@@ -2202,7 +2202,7 @@
"parts_orders": "Parts Orders",
"print": "Show Printed Form",
"receive": "Receive Parts Order",
- "removefrompartsqueue": "Remove from Parts Queue?",
+ "removefrompartsqueue": "Unqueue from Parts Queue?",
"returnpartsorder": "Return Parts Order",
"sublet_order": "Sublet Order"
},
@@ -2455,15 +2455,15 @@
"unsuspend": "Unsuspend"
},
"errors": {
- "boardupdate": "Error encountered updating job. {{message}}",
+ "boardupdate": "Error encountered updating Job. {{message}}",
"removing": "Error removing from production board. {{error}}",
"settings": "Error saving board settings: {{error}}"
},
"labels": {
"actual_in": "Actual In",
"alert": "Alert",
- "alertoff": "Remove alert from job",
- "alerton": "Add alert to job",
+ "alertoff": "Remove alert from Job",
+ "alerton": "Add alert to Job",
"ats": "Alternative Transportation",
"bodyhours": "B",
"bodypriority": "B/P",
@@ -2674,9 +2674,9 @@
"edit": "Edit"
},
"errors": {
- "adding": "Error adding job to scoreboard. {{message}}",
- "removing": "Error removing job from scoreboard. {{message}}",
- "updating": "Error updating scoreboard. {{message}}"
+ "adding": "Error adding Job to Scoreboard. {{message}}",
+ "removing": "Error removing Job from Scoreboard. {{message}}",
+ "updating": "Error updating Scoreboard. {{message}}"
},
"fields": {
"bodyhrs": "Body Hours",
@@ -2774,7 +2774,7 @@
"ro_number": "Job to Post Against"
},
"labels": {
- "alreadyclockedon": "You are already clocked in to the following job(s):",
+ "alreadyclockedon": "You are already clocked in to the following Job(s):",
"ambreak": "AM Break",
"amshift": "AM Shift",
"clockhours": "Shift Clock Hours Summary",
diff --git a/client/src/utils/config.js b/client/src/utils/config.js
new file mode 100644
index 000000000..2a968907c
--- /dev/null
+++ b/client/src/utils/config.js
@@ -0,0 +1,4 @@
+
+// Sometimes referred to as PageSize, this variable controls the amount of records
+// to show on one page during pagination.
+export const pageLimit = 50;
diff --git a/hasura/migrations/1701307239375_alter_table_public_courtesycars_alter_column_nextservicekm/down.sql b/hasura/migrations/1701307239375_alter_table_public_courtesycars_alter_column_nextservicekm/down.sql
new file mode 100644
index 000000000..efc416b2e
--- /dev/null
+++ b/hasura/migrations/1701307239375_alter_table_public_courtesycars_alter_column_nextservicekm/down.sql
@@ -0,0 +1,2 @@
+alter table "public"."courtesycars" alter column "nextservicekm" set not null;
+alter table "public"."courtesycars" alter column "nextservicekm" set default '0';
diff --git a/hasura/migrations/1701307239375_alter_table_public_courtesycars_alter_column_nextservicekm/up.sql b/hasura/migrations/1701307239375_alter_table_public_courtesycars_alter_column_nextservicekm/up.sql
new file mode 100644
index 000000000..3a6640343
--- /dev/null
+++ b/hasura/migrations/1701307239375_alter_table_public_courtesycars_alter_column_nextservicekm/up.sql
@@ -0,0 +1,2 @@
+ALTER TABLE "public"."courtesycars" ALTER COLUMN "nextservicekm" drop default;
+alter table "public"."courtesycars" alter column "nextservicekm" drop not null;
diff --git a/libs/awsUtils.js b/libs/awsUtils.js
new file mode 100644
index 000000000..4f7ee9aa4
--- /dev/null
+++ b/libs/awsUtils.js
@@ -0,0 +1,56 @@
+require("dotenv").config({
+ path: require("path").resolve(
+ process.cwd(),
+ `.env.${process.env.NODE_ENV || "development"}`
+ ),
+});
+const {isNil} = require('lodash');
+const aws4 = require("aws4");
+const {Connection, Client} = require("@opensearch-project/opensearch");
+const {defaultProvider} = require("@aws-sdk/credential-provider-node");
+
+const createAwsConnector = (credentials, region) => {
+ class AmazonConnection extends Connection {
+ buildRequestObject(params) {
+ const request = super.buildRequestObject(params);
+ request.service = "es";
+ request.region = region;
+ request.headers = request.headers || {};
+ request.headers["host"] = request.hostname;
+
+ return aws4.sign(request, credentials);
+ }
+ }
+ return {
+ Connection: AmazonConnection,
+ };
+};
+
+const getClient = async () => {
+
+ // We have manual configuration for OpenSearch,
+ // Return a client using these custom credentials
+ if (
+ !isNil(process.env.OPEN_SEARCH_PASSWORD) &&
+ !isNil(process.env.OPEN_SEARCH_USER) &&
+ !isNil(process.env.OPEN_SEARCH_HOST) &&
+ !isNil(process.env.OPEN_SEARCH_PROTOCOL)
+ ) {
+ // The URI is currently being stored in its entirety, so strip protocol prior to rebuilding it.
+ const hostUrl = process.env.OPEN_SEARCH_HOST.replace(/^https?:\/\//i, '');
+ const node = `${process.env.OPEN_SEARCH_PROTOCOL}://${process.env.OPEN_SEARCH_USER}:${process.env.OPEN_SEARCH_PASSWORD}@${hostUrl}`;
+
+ return new Client({
+ node,
+ });
+ }
+
+ // Default to the AWS Credentials Provider.
+ const credentials = await defaultProvider()();
+ return new Client({
+ ...createAwsConnector(credentials, "ca-central-1"),
+ node: process.env.OPEN_SEARCH_HOST,
+ });
+};
+
+module.exports = { getClient };
\ No newline at end of file
diff --git a/os-loader.js b/os-loader.js
index a7876187a..bdabb87ac 100644
--- a/os-loader.js
+++ b/os-loader.js
@@ -1,59 +1,17 @@
-const Dinero = require("dinero.js");
-
-//const client = require("../graphql-client/graphql-client").client;
-const _ = require("lodash");
-const GraphQLClient = require("graphql-request").GraphQLClient;
-const logger = require("./server/utils/logger");
-
-const path = require("path");
-const client = require("./server/graphql-client/graphql-client").client;
require("dotenv").config({
- path: path.resolve(
- process.cwd(),
- `.env.${process.env.NODE_ENV || "development"}`
+ path: require("path").resolve(
+ process.cwd(),
+ `.env.${process.env.NODE_ENV || "development"}`
),
});
-const { Client, Connection } = require("@opensearch-project/opensearch");
-const { defaultProvider } = require("@aws-sdk/credential-provider-node");
-const aws4 = require("aws4");
-const { gql } = require("graphql-request");
-const gqlclient = require("./server/graphql-client/graphql-client").client;
-// const osClient = new Client({
-// node: `https://imex:Wl0d8k@!@search-imexonline-search-ixp2stfvwp6qocjsowzjzyreoy.ca-central-1.es.amazonaws.com/`,
-// });
-var host = process.env.OPEN_SEARCH_HOST; // e.g. https://my-domain.region.es.amazonaws.com
-const createAwsConnector = (credentials, region) => {
- class AmazonConnection extends Connection {
- buildRequestObject(params) {
- const request = super.buildRequestObject(params);
- request.service = "es";
- request.region = region;
- request.headers = request.headers || {};
- request.headers["host"] = request.hostname;
-
- return aws4.sign(request, credentials);
- }
- }
- return {
- Connection: AmazonConnection,
- };
-};
-
-const getClient = async () => {
- const credentials = await defaultProvider()();
- return new Client({
- ...createAwsConnector(credentials, "ca-central-1"),
- node: host,
- });
-};
+const {omit} = require("lodash");
+const gqlClient = require("./server/graphql-client/graphql-client").client;
+const getClient = require('./libs/awsUtils');
async function OpenSearchUpdateHandler(req, res) {
try {
- var osClient = await getClient();
- // const osClient = new Client({
- // node: `https://imex:password@search-imexonline-search-ixp2stfvwp6qocjsowzjzyreoy.ca-central-1.es.amazonaws.com`,
- // });
+ const osClient = await getClient();
//Clear out all current documents
// const deleteResult = await osClient.deleteByQuery({
@@ -67,11 +25,11 @@ async function OpenSearchUpdateHandler(req, res) {
// return;
- var batchSize = 1000;
- var promiseQueue = [];
+ const batchSize = 1000;
+ const promiseQueue = [];
//Jobs Load.
- const jobsData = await gqlclient.request(`query{jobs{
+ const jobsData = await gqlClient.request(`query{jobs{
id
bodyshopid:shopid
clm_no
@@ -105,7 +63,7 @@ async function OpenSearchUpdateHandler(req, res) {
}
//Owner Load
- const ownersData = await gqlclient.request(`{
+ const ownersData = await gqlClient.request(`{
owners {
id
bodyshopid: shopid
@@ -131,7 +89,7 @@ async function OpenSearchUpdateHandler(req, res) {
}
//Vehicles
- const vehiclesData = await gqlclient.request(`{
+ const vehiclesData = await gqlClient.request(`{
vehicles {
id
bodyshopid: shopid
@@ -158,7 +116,7 @@ async function OpenSearchUpdateHandler(req, res) {
}
//payments
- const paymentsData = await gqlclient.request(`{
+ const paymentsData = await gqlClient.request(`{
payments {
id
amount
@@ -198,7 +156,7 @@ async function OpenSearchUpdateHandler(req, res) {
slicedArray.forEach((payment) => {
bulkOperation.push({ index: { _index: "payments", _id: payment.id } });
bulkOperation.push({
- ..._.omit(payment, ["job"]),
+ ...omit(payment, ["job"]),
bodyshopid: payment.job.bodyshopid,
});
});
@@ -206,7 +164,7 @@ async function OpenSearchUpdateHandler(req, res) {
}
//bills
- const billsData = await gqlclient.request(`{
+ const billsData = await gqlClient.request(`{
bills {
id
date
@@ -235,7 +193,7 @@ async function OpenSearchUpdateHandler(req, res) {
slicedArray.forEach((bill) => {
bulkOperation.push({ index: { _index: "bills", _id: bill.id } });
bulkOperation.push({
- ..._.omit(bill, ["job"]),
+ ...omit(bill, ["job"]),
bodyshopid: bill.job.bodyshopid,
});
});
diff --git a/server/opensearch/os-handler.js b/server/opensearch/os-handler.js
index b6e5fc490..7cb544400 100644
--- a/server/opensearch/os-handler.js
+++ b/server/opensearch/os-handler.js
@@ -1,49 +1,18 @@
-const queries = require("../graphql-client/queries");
-const {pick} = require("lodash");
-const GraphQLClient = require("graphql-request").GraphQLClient;
-const logger = require("../utils/logger");
-//const client = require("../graphql-client/graphql-client").client;
-
-const path = require("path");
-const client = require("../graphql-client/graphql-client").client;
require("dotenv").config({
- path: path.resolve(
+ path: require("path").resolve(
process.cwd(),
`.env.${process.env.NODE_ENV || "development"}`
),
});
-const {Client, Connection} = require("@opensearch-project/opensearch");
-const {defaultProvider} = require("@aws-sdk/credential-provider-node");
-const aws4 = require("aws4");
-const {gql} = require("graphql-request");
-var host = process.env.OPEN_SEARCH_HOST;
+const GraphQLClient = require("graphql-request").GraphQLClient;
+//const client = require("../graphql-client/graphql-client").client;
+const logger = require("../utils/logger");
+const queries = require("../graphql-client/queries");
+const client = require("../graphql-client/graphql-client").client;
+const {pick, isNil} = require("lodash");
+const {getClient} = require('../../libs/awsUtils');
-const createAwsConnector = (credentials, region) => {
- class AmazonConnection extends Connection {
- buildRequestObject(params) {
- const request = super.buildRequestObject(params);
- request.service = "es";
- request.region = region;
- request.headers = request.headers || {};
- request.headers["host"] = request.hostname;
-
- return aws4.sign(request, credentials);
- }
- }
-
- return {
- Connection: AmazonConnection,
- };
-};
-
-const getClient = async () => {
- const credentials = await defaultProvider()();
- return new Client({
- ...createAwsConnector(credentials, "ca-central-1"),
- node: host,
- });
-};
async function OpenSearchUpdateHandler(req, res) {
if (req.headers["event-secret"] !== process.env.EVENT_SECRET) {
@@ -51,10 +20,8 @@ async function OpenSearchUpdateHandler(req, res) {
return;
}
try {
- var osClient = await getClient();
- // const osClient = new Client({
- // node: `https://imex:@search-imexonline-search-ixp2stfvwp6qocjsowzjzyreoy.ca-central-1.es.amazonaws.com/`,
- // });
+
+ const osClient = await getClient();
if (req.body.event.op === "DELETE") {
let response;
@@ -197,14 +164,12 @@ async function OpenSearchUpdateHandler(req, res) {
body: document,
};
- let response;
- response = await osClient.index(payload);
+ const response = await osClient.index(payload);
console.log(response.body);
res.status(200).json(response.body);
}
} catch (error) {
res.status(400).json(JSON.stringify(error));
- } finally {
}
}
@@ -240,6 +205,8 @@ async function OpenSearchSearchHandler(req, res) {
const osClient = await getClient();
+ const bodyShopIdMatchOverride = isNil(process.env.BODY_SHOP_ID_MATCH_OVERRIDE) ? assocs.associations[0].shopid : process.env.BODY_SHOP_ID_MATCH_OVERRIDE
+
const {body} = await osClient.search({
...(index ? {index} : {}),
body: {
@@ -249,7 +216,7 @@ async function OpenSearchSearchHandler(req, res) {
must: [
{
match: {
- bodyshopid: assocs.associations[0].shopid,
+ bodyshopid: bodyShopIdMatchOverride,
},
},
{
@@ -318,7 +285,6 @@ async function OpenSearchSearchHandler(req, res) {
error: JSON.stringify(error),
});
res.status(400).json(error);
- } finally {
}
}