diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index 6fadc58a7..0432eaaf1 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -6369,6 +6369,27 @@
md_parts_scan
+
+ caseInsensitive
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
expression
false
@@ -6390,6 +6411,27 @@
+
+ field
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
flags
false
@@ -6411,6 +6453,48 @@
+
+ operation
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ value
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
@@ -11987,6 +12071,158 @@
+
+ operations
+
+
+ contains
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ ends_with
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ equals
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ greater_than
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ less_than
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ not_equals
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ starts_with
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+
successes
@@ -23131,6 +23367,27 @@
+
+ alt_partno
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
amount
false
@@ -23236,6 +23493,27 @@
+
+ include_in_part_cnt
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
lbr_types
diff --git a/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx b/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx
index 668452b9a..b4dbb2bd1 100644
--- a/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx
+++ b/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx
@@ -192,6 +192,23 @@ export function JobLinesUpsertModalComponent({ bodyshop, open, jobLine, handleCa
+
+ {() => {
+ if (form.getFieldValue("act_price") === 0) {
+ return (
+
+
+
+ );
+ } else {
+ return null;
+ }
+ }}
+
diff --git a/client/src/graphql/jobs-lines.queries.js b/client/src/graphql/jobs-lines.queries.js
index 653cbb9f1..b24978fba 100644
--- a/client/src/graphql/jobs-lines.queries.js
+++ b/client/src/graphql/jobs-lines.queries.js
@@ -238,6 +238,7 @@ export const UPDATE_JOB_LINE = gql`
convertedtolbr
convertedtolbr_data
assigned_team
+ include_in_part_cnt
}
}
}
diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js
index 51b44a1b2..bad1cd9d6 100644
--- a/client/src/graphql/jobs.queries.js
+++ b/client/src/graphql/jobs.queries.js
@@ -581,6 +581,7 @@ export const GET_JOB_BY_PK = gql`
status
tax_part
unq_seq
+ include_in_part_cnt
}
kmin
kmout
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 7f82f69f1..115e050ea 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -256,16 +256,7 @@
}
},
"bodyshop": {
- "operations": {
- "starts_with": "Starts With",
- "contains": "Contains",
- "ends_with": "Ends With",
- "equals": "Equals",
- "not_equals": "Not Equals",
- "greater_than": "Greater Than",
- "less_than": "Less Than"
- },
- "actions": {
+ "actions": {
"add_task_preset": "Add Task Preset",
"addapptcolor": "Add Appointment Color",
"addbucket": "Add Definition",
@@ -388,10 +379,12 @@
"md_lost_sale_reasons": "Lost Sale Reasons",
"md_parts_order_comment": "Parts Orders Comments",
"md_parts_scan": {
+ "caseInsensitive": "Case Insensitive",
+ "expression": "",
"field": "Field",
- "operation": "Operation",
- "value": "Value",
- "caseInsensitive": "Case Insensitive"
+ "flags": "",
+ "operation": "Operation",
+ "value": "Value"
},
"md_payment_types": "Payment Types",
"md_referral_sources": "Referral Sources",
@@ -721,6 +714,15 @@
"task-presets": "Task Presets",
"workingdays": "Working Days"
},
+ "operations": {
+ "contains": "Contains",
+ "ends_with": "Ends With",
+ "equals": "Equals",
+ "greater_than": "Greater Than",
+ "less_than": "Less Than",
+ "not_equals": "Not Equals",
+ "starts_with": "Starts With"
+ },
"successes": {
"areyousure": "Are you sure you want to continue?",
"defaultviewcreated": "Default view created successfully.",
@@ -1434,11 +1436,13 @@
"act_price_before_ppc": "Original Part Price",
"adjustment": "Adjustment",
"ah_detail_line": "Mark as Detail Labor Line (Autohouse Only)",
+ "alt_partno": "Alt Part #",
"amount": "Amount",
"assigned_team": "Team",
"assigned_team_name": "Team {{name}}",
"create_ppc": "Create PPC?",
"db_price": "List Price",
+ "include_in_part_cnt": "Include in Parts Status Count",
"lbr_types": {
"LA1": "LA1",
"LA2": "LA2",
@@ -1463,7 +1467,6 @@
"mod_lbr_ty": "Labor Type",
"notes": "Notes",
"oem_partno": "OEM Part #",
- "alt_partno": "Alt Part #",
"op_code_desc": "Op Code Description",
"part_qty": "Qty.",
"part_type": "Part Type",
@@ -3078,6 +3081,7 @@
"purchase_return_ratio_grouped_by_vendor_summary": "Purchase & Return Ratio by Vendor (Summary)",
"purchases_by_cost_center_detail": "Purchases by Cost Center (Detail)",
"purchases_by_cost_center_summary": "Purchases by Cost Center (Summary)",
+ "purchases_by_date_excel": "Purchases by Date - Excel",
"purchases_by_date_range_detail": "Purchases by Date - Detail",
"purchases_by_date_range_summary": "Purchases by Date - Summary",
"purchases_by_ro_detail_date": "Purchases by RO - Detail",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 6b7f66387..9d5f0ee4c 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -256,16 +256,7 @@
}
},
"bodyshop": {
- "operations": {
- "starts_with": "",
- "contains": "",
- "ends_with": "",
- "equals": "",
- "not_equals": "",
- "greater_than": "",
- "less_than": ""
- },
- "actions": {
+ "actions": {
"add_task_preset": "",
"addapptcolor": "",
"addbucket": "",
@@ -388,10 +379,12 @@
"md_lost_sale_reasons": "",
"md_parts_order_comment": "",
"md_parts_scan": {
+ "caseInsensitive": "",
+ "expression": "",
"field": "",
+ "flags": "",
"operation": "",
- "value": "",
- "caseInsensitive": ""
+ "value": ""
},
"md_payment_types": "",
"md_referral_sources": "",
@@ -721,6 +714,15 @@
"task-presets": "",
"workingdays": ""
},
+ "operations": {
+ "contains": "",
+ "ends_with": "",
+ "equals": "",
+ "greater_than": "",
+ "less_than": "",
+ "not_equals": "",
+ "starts_with": ""
+ },
"successes": {
"areyousure": "",
"defaultviewcreated": "",
@@ -1434,11 +1436,13 @@
"act_price_before_ppc": "",
"adjustment": "",
"ah_detail_line": "",
+ "alt_partno": "",
"amount": "",
"assigned_team": "",
"assigned_team_name": "",
"create_ppc": "",
"db_price": "Precio de base de datos",
+ "include_in_part_cnt": "",
"lbr_types": {
"LA1": "",
"LA2": "",
@@ -1463,8 +1467,7 @@
"mod_lbr_ty": "Tipo de trabajo",
"notes": "",
"oem_partno": "OEM parte #",
- "alt_partno": "",
- "op_code_desc": "",
+ "op_code_desc": "",
"part_qty": "",
"part_type": "Tipo de parte",
"part_types": {
@@ -3078,6 +3081,7 @@
"purchase_return_ratio_grouped_by_vendor_summary": "",
"purchases_by_cost_center_detail": "",
"purchases_by_cost_center_summary": "",
+ "purchases_by_date_excel": "",
"purchases_by_date_range_detail": "",
"purchases_by_date_range_summary": "",
"purchases_by_ro_detail_date": "",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index e7f48c825..44b9fc61c 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -256,16 +256,7 @@
}
},
"bodyshop": {
- "operations": {
- "starts_with": "",
- "contains": "",
- "ends_with": "",
- "equals": "",
- "not_equals": "",
- "greater_than": "",
- "less_than": ""
- },
- "actions": {
+ "actions": {
"add_task_preset": "",
"addapptcolor": "",
"addbucket": "",
@@ -388,10 +379,12 @@
"md_lost_sale_reasons": "",
"md_parts_order_comment": "",
"md_parts_scan": {
+ "caseInsensitive": "",
+ "expression": "",
"field": "",
+ "flags": "",
"operation": "",
- "value": "",
- "caseInsensitive": ""
+ "value": ""
},
"md_payment_types": "",
"md_referral_sources": "",
@@ -721,6 +714,15 @@
"task-presets": "",
"workingdays": ""
},
+ "operations": {
+ "contains": "",
+ "ends_with": "",
+ "equals": "",
+ "greater_than": "",
+ "less_than": "",
+ "not_equals": "",
+ "starts_with": ""
+ },
"successes": {
"areyousure": "",
"defaultviewcreated": "",
@@ -1434,11 +1436,13 @@
"act_price_before_ppc": "",
"adjustment": "",
"ah_detail_line": "",
+ "alt_partno": "",
"amount": "",
"assigned_team": "",
"assigned_team_name": "",
"create_ppc": "",
"db_price": "Prix de la base de données",
+ "include_in_part_cnt": "",
"lbr_types": {
"LA1": "",
"LA2": "",
@@ -1463,8 +1467,7 @@
"mod_lbr_ty": "Type de travail",
"notes": "",
"oem_partno": "Pièce OEM #",
- "alt_partno": "",
- "op_code_desc": "",
+ "op_code_desc": "",
"part_qty": "",
"part_type": "Type de pièce",
"part_types": {
@@ -3078,6 +3081,7 @@
"purchase_return_ratio_grouped_by_vendor_summary": "",
"purchases_by_cost_center_detail": "",
"purchases_by_cost_center_summary": "",
+ "purchases_by_date_excel": "",
"purchases_by_date_range_detail": "",
"purchases_by_date_range_summary": "",
"purchases_by_ro_detail_date": "",
diff --git a/client/src/utils/TemplateConstants.js b/client/src/utils/TemplateConstants.js
index 42241d152..f9d53306c 100644
--- a/client/src/utils/TemplateConstants.js
+++ b/client/src/utils/TemplateConstants.js
@@ -2229,7 +2229,19 @@ export const TemplateList = (type, context) => {
field: i18n.t("jobs.fields.date_open")
},
group: "jobs"
- }
+ },
+ purchases_by_date_excel: {
+ title: i18n.t("reportcenter.templates.purchases_by_date_excel"),
+ subject: i18n.t("reportcenter.templates.purchases_by_date_excel"),
+ key: "purchases_by_date_excel",
+ reporttype: "excel",
+ disabled: false,
+ rangeFilter: {
+ object: i18n.t("reportcenter.labels.objects.bills"),
+ field: i18n.t("bills.fields.date")
+ },
+ group: "purchases"
+ },
}
: {}),
...(!type || type === "courtesycarcontract"
diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml
index d7a010473..4a9416781 100644
--- a/hasura/metadata/tables.yaml
+++ b/hasura/metadata/tables.yaml
@@ -2997,6 +2997,7 @@
- est_seq
- glass_flag
- id
+ - include_in_part_cnt
- ioucreated
- jobid
- lbr_amt
@@ -3066,6 +3067,7 @@
- est_seq
- glass_flag
- id
+ - include_in_part_cnt
- ioucreated
- jobid
- lbr_amt
@@ -3146,6 +3148,7 @@
- est_seq
- glass_flag
- id
+ - include_in_part_cnt
- ioucreated
- jobid
- lbr_amt
diff --git a/hasura/migrations/1620771761757_Init/up.sql b/hasura/migrations/1620771761757_Init/up.sql
index 3b608100b..0bdef8e89 100644
--- a/hasura/migrations/1620771761757_Init/up.sql
+++ b/hasura/migrations/1620771761757_Init/up.sql
@@ -39,50 +39,50 @@ END;
$$;
CREATE FUNCTION public.assign_ro_number() RETURNS trigger
LANGUAGE plpgsql
- AS $$
- begin
- IF NEW.converted = true and (new.ro_number is null or new.ro_number = '') THEN
- UPDATE counters
- SET count = count + 1 where shopid=new.shopid AND countertype = 'ronum'
- RETURNING concat(prefix,count) into new.ro_number;
- END IF;
- RETURN NEW;
- END;
+ AS $$
+ begin
+ IF NEW.converted = true and (new.ro_number is null or new.ro_number = '') THEN
+ UPDATE counters
+ SET count = count + 1 where shopid=new.shopid AND countertype = 'ronum'
+ RETURNING concat(prefix,count) into new.ro_number;
+ END IF;
+ RETURN NEW;
+ END;
$$;
CREATE FUNCTION public.audit_trigger() RETURNS trigger
LANGUAGE plpgsql SECURITY DEFINER
- AS $$
- DECLARE
- shopid uuid ;
- email text;
- BEGIN
- select b.id, u.email INTO shopid, email from users u join associations a on u.email = a.useremail join bodyshops b on b.id = a.shopid where u.authid = current_setting('hasura.user', 't')::jsonb->>'x-hasura-user-id' and a.active = true;
- IF TG_OP = 'INSERT'
- THEN
- INSERT INTO public.audit_trail (tabname, schemaname, operation, new_val, recordid, bodyshopid, useremail)
- VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(NEW), NEW.id, shopid, email);
- RETURN NEW;
- ELSIF TG_OP = 'UPDATE'
- THEN
- INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, new_val, recordid, bodyshopid, useremail)
- VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
- json_diff(to_jsonb(OLD), to_jsonb(NEW)) , json_diff(to_jsonb(NEW), to_jsonb(OLD)), OLD.id, shopid, email);
- RETURN NEW;
- ELSIF TG_OP = 'DELETE'
- THEN
- INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, recordid, bodyshopid, useremail)
- VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD), OLD.ID, shopid, email);
- RETURN OLD;
- END IF;
- END;
+ AS $$
+ DECLARE
+ shopid uuid ;
+ email text;
+ BEGIN
+ select b.id, u.email INTO shopid, email from users u join associations a on u.email = a.useremail join bodyshops b on b.id = a.shopid where u.authid = current_setting('hasura.user', 't')::jsonb->>'x-hasura-user-id' and a.active = true;
+ IF TG_OP = 'INSERT'
+ THEN
+ INSERT INTO public.audit_trail (tabname, schemaname, operation, new_val, recordid, bodyshopid, useremail)
+ VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(NEW), NEW.id, shopid, email);
+ RETURN NEW;
+ ELSIF TG_OP = 'UPDATE'
+ THEN
+ INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, new_val, recordid, bodyshopid, useremail)
+ VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
+ json_diff(to_jsonb(OLD), to_jsonb(NEW)) , json_diff(to_jsonb(NEW), to_jsonb(OLD)), OLD.id, shopid, email);
+ RETURN NEW;
+ ELSIF TG_OP = 'DELETE'
+ THEN
+ INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, recordid, bodyshopid, useremail)
+ VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD), OLD.ID, shopid, email);
+ RETURN OLD;
+ END IF;
+ END;
$$;
CREATE FUNCTION public.json_diff(l jsonb, r jsonb) RETURNS jsonb
LANGUAGE sql
- AS $$
- SELECT jsonb_object_agg(a.key, a.value) FROM
- ( SELECT key, value FROM jsonb_each(l) ) a LEFT OUTER JOIN
- ( SELECT key, value FROM jsonb_each(r) ) b ON a.key = b.key
- WHERE a.value != b.value OR b.key IS NULL;
+ AS $$
+ SELECT jsonb_object_agg(a.key, a.value) FROM
+ ( SELECT key, value FROM jsonb_each(l) ) a LEFT OUTER JOIN
+ ( SELECT key, value FROM jsonb_each(r) ) b ON a.key = b.key
+ WHERE a.value != b.value OR b.key IS NULL;
$$;
CREATE TABLE public.bills (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
@@ -211,33 +211,33 @@ CREATE TABLE public.exportlog (
);
CREATE FUNCTION public.search_exportlog(search text) RETURNS SETOF public.exportlog
LANGUAGE plpgsql STABLE
- AS $$ BEGIN IF search = '' THEN RETURN query
-SELECT
- *
-FROM
- exportlog e;
- ELSE RETURN query
-SELECT
- e.*
-FROM
- exportlog e
- LEFT JOIN jobs j on j.id = e.jobid
-LEFT JOIN payments p
- ON p.id = e.paymentid
-LEFT JOIN bills b
- ON e.billid = b.id
-WHERE
- (
- j.ro_number ILIKE '%' || search || '%'
- OR b.invoice_number ILIKE '%' || search || '%'
- OR p.paymentnum ILIKE '%' || search || '%'
- OR e.useremail ILIKE '%' || search || '%'
- )
- AND (e.jobid = j.id
- or e.paymentid = p.id
- or e.billid = b.id)
-;
-END IF;
+ AS $$ BEGIN IF search = '' THEN RETURN query
+SELECT
+ *
+FROM
+ exportlog e;
+ ELSE RETURN query
+SELECT
+ e.*
+FROM
+ exportlog e
+ LEFT JOIN jobs j on j.id = e.jobid
+LEFT JOIN payments p
+ ON p.id = e.paymentid
+LEFT JOIN bills b
+ ON e.billid = b.id
+WHERE
+ (
+ j.ro_number ILIKE '%' || search || '%'
+ OR b.invoice_number ILIKE '%' || search || '%'
+ OR p.paymentnum ILIKE '%' || search || '%'
+ OR e.useremail ILIKE '%' || search || '%'
+ )
+ AND (e.jobid = j.id
+ or e.paymentid = p.id
+ or e.billid = b.id)
+;
+END IF;
END $$;
CREATE TABLE public.jobs (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
diff --git a/hasura/migrations/1736889526400_alter_table_public_joblines_add_column_include_in_part_cnt/down.sql b/hasura/migrations/1736889526400_alter_table_public_joblines_add_column_include_in_part_cnt/down.sql
new file mode 100644
index 000000000..00fb86751
--- /dev/null
+++ b/hasura/migrations/1736889526400_alter_table_public_joblines_add_column_include_in_part_cnt/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"."joblines" add column "include_in_part_cnt" boolean
+-- not null default 'false';
diff --git a/hasura/migrations/1736889526400_alter_table_public_joblines_add_column_include_in_part_cnt/up.sql b/hasura/migrations/1736889526400_alter_table_public_joblines_add_column_include_in_part_cnt/up.sql
new file mode 100644
index 000000000..e6263e93f
--- /dev/null
+++ b/hasura/migrations/1736889526400_alter_table_public_joblines_add_column_include_in_part_cnt/up.sql
@@ -0,0 +1,2 @@
+alter table "public"."joblines" add column "include_in_part_cnt" boolean
+ not null default 'false';
diff --git a/hasura/migrations/1736890690896_run_sql_migration/down.sql b/hasura/migrations/1736890690896_run_sql_migration/down.sql
new file mode 100644
index 000000000..c42aeda5c
--- /dev/null
+++ b/hasura/migrations/1736890690896_run_sql_migration/down.sql
@@ -0,0 +1,10 @@
+-- Could not auto-generate a down migration.
+-- Please write an appropriate down migration for the SQL below:
+-- CREATE OR REPLACE VIEW "public"."joblines_status" AS
+-- SELECT j.jobid,
+-- j.status,
+-- count(1) AS count,
+-- j.part_type
+-- FROM joblines j
+-- WHERE ((j.part_type IS NOT NULL) AND (j.part_type <> 'PAE'::text) AND (j.part_type <> 'PAS'::text) AND (j.part_type <> 'PASL'::text) AND ((j.part_qty)::numeric <> (0)::numeric) AND ((j.act_price <> (0)::numeric) OR (j.include_in_part_cnt is TRUE))AND (j.removed IS FALSE))
+-- GROUP BY j.jobid, j.status, j.part_type;
diff --git a/hasura/migrations/1736890690896_run_sql_migration/up.sql b/hasura/migrations/1736890690896_run_sql_migration/up.sql
new file mode 100644
index 000000000..054c8ea0a
--- /dev/null
+++ b/hasura/migrations/1736890690896_run_sql_migration/up.sql
@@ -0,0 +1,8 @@
+CREATE OR REPLACE VIEW "public"."joblines_status" AS
+ SELECT j.jobid,
+ j.status,
+ count(1) AS count,
+ j.part_type
+ FROM joblines j
+ WHERE ((j.part_type IS NOT NULL) AND (j.part_type <> 'PAE'::text) AND (j.part_type <> 'PAS'::text) AND (j.part_type <> 'PASL'::text) AND ((j.part_qty)::numeric <> (0)::numeric) AND ((j.act_price <> (0)::numeric) OR (j.include_in_part_cnt is TRUE))AND (j.removed IS FALSE))
+ GROUP BY j.jobid, j.status, j.part_type;
diff --git a/hasura/migrations/1736890701752_run_sql_migration/down.sql b/hasura/migrations/1736890701752_run_sql_migration/down.sql
new file mode 100644
index 000000000..c42aeda5c
--- /dev/null
+++ b/hasura/migrations/1736890701752_run_sql_migration/down.sql
@@ -0,0 +1,10 @@
+-- Could not auto-generate a down migration.
+-- Please write an appropriate down migration for the SQL below:
+-- CREATE OR REPLACE VIEW "public"."joblines_status" AS
+-- SELECT j.jobid,
+-- j.status,
+-- count(1) AS count,
+-- j.part_type
+-- FROM joblines j
+-- WHERE ((j.part_type IS NOT NULL) AND (j.part_type <> 'PAE'::text) AND (j.part_type <> 'PAS'::text) AND (j.part_type <> 'PASL'::text) AND ((j.part_qty)::numeric <> (0)::numeric) AND ((j.act_price <> (0)::numeric) OR (j.include_in_part_cnt is TRUE))AND (j.removed IS FALSE))
+-- GROUP BY j.jobid, j.status, j.part_type;
diff --git a/hasura/migrations/1736890701752_run_sql_migration/up.sql b/hasura/migrations/1736890701752_run_sql_migration/up.sql
new file mode 100644
index 000000000..054c8ea0a
--- /dev/null
+++ b/hasura/migrations/1736890701752_run_sql_migration/up.sql
@@ -0,0 +1,8 @@
+CREATE OR REPLACE VIEW "public"."joblines_status" AS
+ SELECT j.jobid,
+ j.status,
+ count(1) AS count,
+ j.part_type
+ FROM joblines j
+ WHERE ((j.part_type IS NOT NULL) AND (j.part_type <> 'PAE'::text) AND (j.part_type <> 'PAS'::text) AND (j.part_type <> 'PASL'::text) AND ((j.part_qty)::numeric <> (0)::numeric) AND ((j.act_price <> (0)::numeric) OR (j.include_in_part_cnt is TRUE))AND (j.removed IS FALSE))
+ GROUP BY j.jobid, j.status, j.part_type;
diff --git a/hasura/migrations_backup/1620771761757_Init/up.sql b/hasura/migrations_backup/1620771761757_Init/up.sql
index 3b608100b..0bdef8e89 100644
--- a/hasura/migrations_backup/1620771761757_Init/up.sql
+++ b/hasura/migrations_backup/1620771761757_Init/up.sql
@@ -39,50 +39,50 @@ END;
$$;
CREATE FUNCTION public.assign_ro_number() RETURNS trigger
LANGUAGE plpgsql
- AS $$
- begin
- IF NEW.converted = true and (new.ro_number is null or new.ro_number = '') THEN
- UPDATE counters
- SET count = count + 1 where shopid=new.shopid AND countertype = 'ronum'
- RETURNING concat(prefix,count) into new.ro_number;
- END IF;
- RETURN NEW;
- END;
+ AS $$
+ begin
+ IF NEW.converted = true and (new.ro_number is null or new.ro_number = '') THEN
+ UPDATE counters
+ SET count = count + 1 where shopid=new.shopid AND countertype = 'ronum'
+ RETURNING concat(prefix,count) into new.ro_number;
+ END IF;
+ RETURN NEW;
+ END;
$$;
CREATE FUNCTION public.audit_trigger() RETURNS trigger
LANGUAGE plpgsql SECURITY DEFINER
- AS $$
- DECLARE
- shopid uuid ;
- email text;
- BEGIN
- select b.id, u.email INTO shopid, email from users u join associations a on u.email = a.useremail join bodyshops b on b.id = a.shopid where u.authid = current_setting('hasura.user', 't')::jsonb->>'x-hasura-user-id' and a.active = true;
- IF TG_OP = 'INSERT'
- THEN
- INSERT INTO public.audit_trail (tabname, schemaname, operation, new_val, recordid, bodyshopid, useremail)
- VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(NEW), NEW.id, shopid, email);
- RETURN NEW;
- ELSIF TG_OP = 'UPDATE'
- THEN
- INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, new_val, recordid, bodyshopid, useremail)
- VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
- json_diff(to_jsonb(OLD), to_jsonb(NEW)) , json_diff(to_jsonb(NEW), to_jsonb(OLD)), OLD.id, shopid, email);
- RETURN NEW;
- ELSIF TG_OP = 'DELETE'
- THEN
- INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, recordid, bodyshopid, useremail)
- VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD), OLD.ID, shopid, email);
- RETURN OLD;
- END IF;
- END;
+ AS $$
+ DECLARE
+ shopid uuid ;
+ email text;
+ BEGIN
+ select b.id, u.email INTO shopid, email from users u join associations a on u.email = a.useremail join bodyshops b on b.id = a.shopid where u.authid = current_setting('hasura.user', 't')::jsonb->>'x-hasura-user-id' and a.active = true;
+ IF TG_OP = 'INSERT'
+ THEN
+ INSERT INTO public.audit_trail (tabname, schemaname, operation, new_val, recordid, bodyshopid, useremail)
+ VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(NEW), NEW.id, shopid, email);
+ RETURN NEW;
+ ELSIF TG_OP = 'UPDATE'
+ THEN
+ INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, new_val, recordid, bodyshopid, useremail)
+ VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
+ json_diff(to_jsonb(OLD), to_jsonb(NEW)) , json_diff(to_jsonb(NEW), to_jsonb(OLD)), OLD.id, shopid, email);
+ RETURN NEW;
+ ELSIF TG_OP = 'DELETE'
+ THEN
+ INSERT INTO public.audit_trail (tabname, schemaname, operation, old_val, recordid, bodyshopid, useremail)
+ VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD), OLD.ID, shopid, email);
+ RETURN OLD;
+ END IF;
+ END;
$$;
CREATE FUNCTION public.json_diff(l jsonb, r jsonb) RETURNS jsonb
LANGUAGE sql
- AS $$
- SELECT jsonb_object_agg(a.key, a.value) FROM
- ( SELECT key, value FROM jsonb_each(l) ) a LEFT OUTER JOIN
- ( SELECT key, value FROM jsonb_each(r) ) b ON a.key = b.key
- WHERE a.value != b.value OR b.key IS NULL;
+ AS $$
+ SELECT jsonb_object_agg(a.key, a.value) FROM
+ ( SELECT key, value FROM jsonb_each(l) ) a LEFT OUTER JOIN
+ ( SELECT key, value FROM jsonb_each(r) ) b ON a.key = b.key
+ WHERE a.value != b.value OR b.key IS NULL;
$$;
CREATE TABLE public.bills (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
@@ -211,33 +211,33 @@ CREATE TABLE public.exportlog (
);
CREATE FUNCTION public.search_exportlog(search text) RETURNS SETOF public.exportlog
LANGUAGE plpgsql STABLE
- AS $$ BEGIN IF search = '' THEN RETURN query
-SELECT
- *
-FROM
- exportlog e;
- ELSE RETURN query
-SELECT
- e.*
-FROM
- exportlog e
- LEFT JOIN jobs j on j.id = e.jobid
-LEFT JOIN payments p
- ON p.id = e.paymentid
-LEFT JOIN bills b
- ON e.billid = b.id
-WHERE
- (
- j.ro_number ILIKE '%' || search || '%'
- OR b.invoice_number ILIKE '%' || search || '%'
- OR p.paymentnum ILIKE '%' || search || '%'
- OR e.useremail ILIKE '%' || search || '%'
- )
- AND (e.jobid = j.id
- or e.paymentid = p.id
- or e.billid = b.id)
-;
-END IF;
+ AS $$ BEGIN IF search = '' THEN RETURN query
+SELECT
+ *
+FROM
+ exportlog e;
+ ELSE RETURN query
+SELECT
+ e.*
+FROM
+ exportlog e
+ LEFT JOIN jobs j on j.id = e.jobid
+LEFT JOIN payments p
+ ON p.id = e.paymentid
+LEFT JOIN bills b
+ ON e.billid = b.id
+WHERE
+ (
+ j.ro_number ILIKE '%' || search || '%'
+ OR b.invoice_number ILIKE '%' || search || '%'
+ OR p.paymentnum ILIKE '%' || search || '%'
+ OR e.useremail ILIKE '%' || search || '%'
+ )
+ AND (e.jobid = j.id
+ or e.paymentid = p.id
+ or e.billid = b.id)
+;
+END IF;
END $$;
CREATE TABLE public.jobs (
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
diff --git a/server/data/usageReport.js b/server/data/usageReport.js
index dd7bb4d42..42a8b5451 100644
--- a/server/data/usageReport.js
+++ b/server/data/usageReport.js
@@ -34,7 +34,7 @@ exports.default = async (req, res) => {
//Query the usage data.
const queryResults = await client.request(queries.STATUS_UPDATE, {
- today: moment().startOf("day").subtract(3, "days"),
+ today: moment().startOf("day").subtract(7, "days"),
period: moment().subtract(90, "days").startOf("day")
});
@@ -63,7 +63,7 @@ Usage Report for ${moment().format("MM/DD/YYYY")} for Rome Online Customers.
Notes:
- Days Since Creation: The number of days since the shop was created. Only shops created in the last 90 days are included.
- Updated values should be higher than created values.
- - Counts are inclusive of the last 3 days of data.
+ - Counts are inclusive of the last 7 days of data.
`,
attachments: [{ filename: `RO Usage Report ${moment().format("MM/DD/YYYY")}.csv`, content: csv }]
})