Compare commits
3 commits
e67805c01f
...
5b2e362100
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b2e362100 | ||
|
|
f386edf769 | ||
|
|
c0b1f3f37a |
5 changed files with 112 additions and 88 deletions
|
|
@ -25,7 +25,7 @@ def create_job_from_sales_order(sales_order_name):
|
||||||
try:
|
try:
|
||||||
sales_order = frappe.get_doc("Sales Order", sales_order_name)
|
sales_order = frappe.get_doc("Sales Order", sales_order_name)
|
||||||
project_template = frappe.get_doc("Project Template", "SNW Install")
|
project_template = frappe.get_doc("Project Template", "SNW Install")
|
||||||
new_job = frappe.get_doc({
|
new_project = frappe.get_doc({
|
||||||
"doctype": "Project",
|
"doctype": "Project",
|
||||||
"custom_address": sales_order.custom_job_address,
|
"custom_address": sales_order.custom_job_address,
|
||||||
# "custom_installation_address": sales_order.custom_installation_address,
|
# "custom_installation_address": sales_order.custom_installation_address,
|
||||||
|
|
@ -35,13 +35,22 @@ def create_job_from_sales_order(sales_order_name):
|
||||||
"sales_order": sales_order,
|
"sales_order": sales_order,
|
||||||
"custom_company": sales_order.company
|
"custom_company": sales_order.company
|
||||||
})
|
})
|
||||||
new_job.insert()
|
new_project.insert()
|
||||||
|
for sales_order_item in sales_order.items:
|
||||||
|
new_task = frappe.get_doc({
|
||||||
|
"doctype": "Task",
|
||||||
|
"project": new_project.name,
|
||||||
|
"company": sales_order.company,
|
||||||
|
"custom_property": sales_order.custom_job_address,
|
||||||
|
"subject": sales_order_item.description,
|
||||||
|
})
|
||||||
|
new_task.insert()
|
||||||
# Iterate through new tasks (if any) and set customer, address
|
# Iterate through new tasks (if any) and set customer, address
|
||||||
# job_tasks = frappe.get_all("Task", filters={"Project": new_job.name})
|
# job_tasks = frappe.get_all("Task", filters={"Project": new_job.name})
|
||||||
# for task in job_tasks:
|
# for task in job_tasks:
|
||||||
# task.custom_property = new_job.job_address
|
# task.custom_property = new_job.job_address
|
||||||
# task.save()
|
# task.save()
|
||||||
return build_success_response(new_job.as_dict())
|
return build_success_response(new_project.as_dict())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return build_error_response(str(e), 500)
|
return build_error_response(str(e), 500)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,33 +43,32 @@ def get_task_status_options():
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_tasks_due(subject_filter):
|
def get_tasks_due(subject_filter, current_company):
|
||||||
"""Return the number of items due today of the type of subject_filter"""
|
"""Return the number of items due today of the type of subject_filter"""
|
||||||
try:
|
try:
|
||||||
filters = {
|
|
||||||
'subject': ['like', f'%{subject_filter}%'],
|
|
||||||
'status': ['not in', ["Template", "Completed", "Cancelled"]]
|
|
||||||
}
|
|
||||||
count = frappe.db.count("Task", filters=filters)
|
|
||||||
return build_success_response(count)
|
|
||||||
except frappe.ValidationError as ve:
|
|
||||||
return build_error_response(str(ve), 400)
|
|
||||||
except Exception as e:
|
|
||||||
return build_error_response(str(e), 500)
|
|
||||||
|
|
||||||
|
due_filters = {
|
||||||
@frappe.whitelist()
|
|
||||||
def get_tasks_completed(subject_filter):
|
|
||||||
"""Return the number of items due today marked complete of the type of subject_filter"""
|
|
||||||
try:
|
|
||||||
filters = {
|
|
||||||
'subject': ['like', f'%{subject_filter}%'],
|
'subject': ['like', f'%{subject_filter}%'],
|
||||||
'status': ['not in', ["Template", "Cancelled"]]
|
'status': ['not in', ["Template", "Completed", "Cancelled"]],
|
||||||
|
'company': current_company,
|
||||||
|
# Add due date filter here
|
||||||
}
|
}
|
||||||
print("Completed Task filter", filters)
|
completed_filters = {
|
||||||
count = frappe.db.count("Task", filters=filters)
|
'subject': ['like', f'%{subject_filter}%'],
|
||||||
print("Matching Records:", count)
|
'status': ['not in', ["Template", "Cancelled"]],
|
||||||
return build_success_response(count)
|
'company': current_company,
|
||||||
|
# Add due date filter here
|
||||||
|
}
|
||||||
|
overdue_filters = {
|
||||||
|
'subject': ['like', f'%{subject_filter}%'],
|
||||||
|
'status': ['not in', ["Template", "Completed", "Cancelled"]],
|
||||||
|
'company': current_company,
|
||||||
|
# Add overdue date filtering here
|
||||||
|
}
|
||||||
|
due_count = frappe.db.count("Task", filters=due_filters)
|
||||||
|
completed_count = frappe.db.count("Task", filters=completed_filters)
|
||||||
|
overdue_count = frappe.db.count("Task", filters=overdue_filters)
|
||||||
|
return build_success_response([due_count, completed_count, overdue_count])
|
||||||
except frappe.ValidationError as ve:
|
except frappe.ValidationError as ve:
|
||||||
return build_error_response(str(ve), 400)
|
return build_error_response(str(ve), 400)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ const FRAPPE_LOCK_ESTIMATE_METHOD = "custom_ui.api.db.estimates.lock_estimate";
|
||||||
const FRAPPE_ESTIMATE_UPDATE_RESPONSE_METHOD = "custom_ui.api.db.estimates.manual_response";
|
const FRAPPE_ESTIMATE_UPDATE_RESPONSE_METHOD = "custom_ui.api.db.estimates.manual_response";
|
||||||
const FRAPPE_GET_ESTIMATE_TEMPLATES_METHOD = "custom_ui.api.db.estimates.get_estimate_templates";
|
const FRAPPE_GET_ESTIMATE_TEMPLATES_METHOD = "custom_ui.api.db.estimates.get_estimate_templates";
|
||||||
const FRAPPE_CREATE_ESTIMATE_TEMPLATE_METHOD = "custom_ui.api.db.estimates.create_estimate_template";
|
const FRAPPE_CREATE_ESTIMATE_TEMPLATE_METHOD = "custom_ui.api.db.estimates.create_estimate_template";
|
||||||
|
const FRAPPE_GET_UNAPPROVED_ESTIMATES_COUNT_METHOD = "custom_ui.api.db.estimates.get_unnaproved_estimates_count";
|
||||||
|
const FRAPPE_GET_ESTIMATES_HALF_DOWN_COUNT_METHOD = "custom_ui.api.db.estimates.get_estimates_half_down_count";
|
||||||
// Job methods
|
// Job methods
|
||||||
const FRAPPE_GET_JOB_METHOD = "custom_ui.api.db.jobs.get_job";
|
const FRAPPE_GET_JOB_METHOD = "custom_ui.api.db.jobs.get_job";
|
||||||
const FRAPPE_GET_JOBS_METHOD = "custom_ui.api.db.jobs.get_jobs_table_data";
|
const FRAPPE_GET_JOBS_METHOD = "custom_ui.api.db.jobs.get_jobs_table_data";
|
||||||
|
|
@ -29,7 +31,6 @@ const FRAPPE_GET_TASKS_METHOD = "custom_ui.api.db.tasks.get_tasks_table_data";
|
||||||
const FRAPPE_GET_TASKS_STATUS_OPTIONS = "custom_ui.api.db.tasks.get_task_status_options";
|
const FRAPPE_GET_TASKS_STATUS_OPTIONS = "custom_ui.api.db.tasks.get_task_status_options";
|
||||||
const FRAPPE_SET_TASK_STATUS_METHOD = "custom_ui.api.db.tasks.set_task_status";
|
const FRAPPE_SET_TASK_STATUS_METHOD = "custom_ui.api.db.tasks.set_task_status";
|
||||||
const FRAPPE_GET_TASKS_DUE_METHOD = "custom_ui.api.db.tasks.get_tasks_due";
|
const FRAPPE_GET_TASKS_DUE_METHOD = "custom_ui.api.db.tasks.get_tasks_due";
|
||||||
const FRAPPE_GET_TASKS_COMPLETED_METHOD = "custom_ui.api.db.tasks.get_tasks_completed";
|
|
||||||
// Invoice methods
|
// Invoice methods
|
||||||
const FRAPPE_GET_INVOICES_METHOD = "custom_ui.api.db.invoices.get_invoice_table_data";
|
const FRAPPE_GET_INVOICES_METHOD = "custom_ui.api.db.invoices.get_invoice_table_data";
|
||||||
const FRAPPE_UPSERT_INVOICE_METHOD = "custom_ui.api.db.invoices.upsert_invoice";
|
const FRAPPE_UPSERT_INVOICE_METHOD = "custom_ui.api.db.invoices.upsert_invoice";
|
||||||
|
|
@ -264,6 +265,14 @@ class Api {
|
||||||
return await this.request(FRAPPE_CREATE_ESTIMATE_TEMPLATE_METHOD, { data });
|
return await this.request(FRAPPE_CREATE_ESTIMATE_TEMPLATE_METHOD, { data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async getUnapprovedEstimatesCount() {
|
||||||
|
return await this.request(FRAPPE_GET_UNAPPROVED_ESTIMATES_COUNT_METHOD, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getEstimatesHalfDownCount() {
|
||||||
|
return await this.request(FRAPPE_GET_ESTIMATES_HALF_DOWN_COUNT_METHOD, {});
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// JOB / PROJECT METHODS
|
// JOB / PROJECT METHODS
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
@ -436,8 +445,8 @@ class Api {
|
||||||
return await this.request(FRAPPE_SET_TASK_STATUS_METHOD, { taskName, newStatus });
|
return await this.request(FRAPPE_SET_TASK_STATUS_METHOD, { taskName, newStatus });
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getTasksDue(subjectFilter) {
|
static async getTasksDue(subjectFilter, currentCompany) {
|
||||||
const result = await this.request(FRAPPE_GET_TASKS_DUE_METHOD, {subjectFilter});
|
const result = await this.request(FRAPPE_GET_TASKS_DUE_METHOD, {subjectFilter, currentCompany});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch, nextTick, computed, onUnmounted} from "vue";
|
import { ref, onMounted, watch, nextTick, computed, onUnmounted, toRaw} from "vue";
|
||||||
import { Chart, registerables } from "chart.js";
|
import { Chart, registerables } from "chart.js";
|
||||||
|
|
||||||
// Register Chart.js components
|
// Register Chart.js components
|
||||||
|
|
@ -29,8 +29,7 @@ Chart.register(...registerables);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: String,
|
title: String,
|
||||||
todoNumber: Number,
|
categories: Object,
|
||||||
completedNumber: Number,
|
|
||||||
loading: {
|
loading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
@ -38,7 +37,7 @@ const props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
//Constants
|
//Constants
|
||||||
const categories = ["To-do", "Completed"];
|
//const categories = ["To-do", "Completed"];
|
||||||
|
|
||||||
//Reactive data
|
//Reactive data
|
||||||
const centerData = ref(null);
|
const centerData = ref(null);
|
||||||
|
|
@ -56,21 +55,19 @@ const getHoveredCategoryIndex = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCategoryValue = (categoryIndex) => {
|
const getCategoryValue = (categoryIndex) => {
|
||||||
if (categoryIndex === 0) {
|
return props.categories.data[categoryIndex];
|
||||||
return props.todoNumber
|
|
||||||
} else {
|
|
||||||
return props.completedNumber
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getChartData = () => {
|
const getChartData = () => {
|
||||||
|
const categoryData = props.categories.data;
|
||||||
|
const categoryColors = props.categories.colors;
|
||||||
const chartData = {
|
const chartData = {
|
||||||
name: props.title,
|
name: props.title,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "",
|
label: "",
|
||||||
data: [props.todoNumber, props.completedNumber],
|
data: categoryData,
|
||||||
backgroundColor: ["#b22222", "#4caf50"]
|
backgroundColor: categoryColors
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
@ -79,8 +76,11 @@ const getChartData = () => {
|
||||||
|
|
||||||
|
|
||||||
const updateCenterData = () => {
|
const updateCenterData = () => {
|
||||||
const total = props.todoNumber + props.completedNumber;
|
let total = 0;
|
||||||
const todos = props.todoNumber;
|
for (let i=0; i<props.categories.data.length; i++) {
|
||||||
|
total += props.categories.data[i];
|
||||||
|
}
|
||||||
|
const todos = props.categories.data[0];
|
||||||
|
|
||||||
if (todos === 0 && total > 0) {
|
if (todos === 0 && total > 0) {
|
||||||
centerData.value = {
|
centerData.value = {
|
||||||
|
|
@ -107,14 +107,14 @@ const updateCenterData = () => {
|
||||||
const percentage = total > 0 ? ((value / total) * 100).toFixed(1) + "%" : "0%";
|
const percentage = total > 0 ? ((value / total) * 100).toFixed(1) + "%" : "0%";
|
||||||
|
|
||||||
centerData.value = {
|
centerData.value = {
|
||||||
label: categories[hoveredCategoryIndex],
|
label: props.categories.labels[hoveredCategoryIndex],
|
||||||
value: value,
|
value: value,
|
||||||
percentage: percentage,
|
percentage: percentage,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
centerData.value = {
|
centerData.value = {
|
||||||
label: "To-do",
|
label: "To-do",
|
||||||
value: props.todoNumber,
|
value: todos,
|
||||||
percentage: null,
|
percentage: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -180,8 +180,6 @@ const getChartOptions = () => {
|
||||||
const createChart = () => {
|
const createChart = () => {
|
||||||
if (!chartCanvas.value || props.loading) return;
|
if (!chartCanvas.value || props.loading) return;
|
||||||
|
|
||||||
console.log(`DEBUG: Creating chart for ${props.title}`);
|
|
||||||
console.log(props);
|
|
||||||
|
|
||||||
const ctx = chartCanvas.value.getContext("2d");
|
const ctx = chartCanvas.value.getContext("2d");
|
||||||
if (chartInstance.value) {
|
if (chartInstance.value) {
|
||||||
|
|
@ -214,9 +212,9 @@ onMounted(() => {
|
||||||
createChart();
|
createChart();
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => props.completedNumber, (newValue) => {
|
watch(() => props.categories, (newValue) => {
|
||||||
updateChart();
|
updateChart();
|
||||||
});
|
}, {deep: true});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Locates"
|
title="Locates"
|
||||||
:todoNumber="chartData.locates.todo"
|
:categories="chartData.locates"
|
||||||
:completedNumber="chartData.locates.done"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button" @click="navigateTo('/tasks?subject=Locate')">
|
<button class="sidebar-button" @click="navigateTo('/tasks?subject=Locate')">
|
||||||
|
|
@ -37,8 +36,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Permits"
|
title="Permits"
|
||||||
:todoNumber="chartData.permits.todo"
|
:categories="chartData.permits"
|
||||||
:completedNumber="chartData.permits.done"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button" @click="navigateTo('/tasks?subject=Permit')">
|
<button class="sidebar-button" @click="navigateTo('/tasks?subject=Permit')">
|
||||||
|
|
@ -59,8 +57,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Permit Finalization"
|
title="Permit Finalization"
|
||||||
:todoNumber="permitFinalizationsTodoNumber"
|
:categories="chartData.permitFinalizations"
|
||||||
:completedNumber="permitFinalizationsCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button" @click="navigateTo('/jobs')">
|
<button class="sidebar-button" @click="navigateTo('/jobs')">
|
||||||
|
|
@ -81,8 +78,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Warranty Claims"
|
title="Warranty Claims"
|
||||||
:todoNumber="warrantyTodoNumber"
|
:categories="chartData.warranties"
|
||||||
:completedNumber="warrantyCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button" @click="navigateTo('/jobs')">
|
<button class="sidebar-button" @click="navigateTo('/jobs')">
|
||||||
|
|
@ -103,8 +99,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Incomplete Bids"
|
title="Incomplete Bids"
|
||||||
:todoNumber="bidsTodoNumber"
|
:categories="chartData.bids"
|
||||||
:completedNumber="bidsCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -126,8 +121,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Unapproved Estimates"
|
title="Unapproved Estimates"
|
||||||
:todoNumber="estimatesTodoNumber"
|
:categories="chartData.estimates"
|
||||||
:completedNumber="estimatesCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -149,8 +143,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Half Down Payments"
|
title="Half Down Payments"
|
||||||
:todoNumber="halfDownTodoNumber"
|
:categories="chartData.halfDown"
|
||||||
:completedNumber="halfDownCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -172,8 +165,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="15 Day Follow Ups"
|
title="15 Day Follow Ups"
|
||||||
:todoNumber="fifteenDayTodoNumber"
|
:categories="chartData.fifteenDayFollowups"
|
||||||
:completedNumber="fifteenDayCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -195,8 +187,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Late Balances"
|
title="Late Balances"
|
||||||
:todoNumber="balancesTodoNumber"
|
:categories="chartData.lateBalances"
|
||||||
:completedNumber="balancesCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -218,8 +209,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Backflow Tests"
|
title="Backflow Tests"
|
||||||
:todoNumber="backflowsTodoNumber"
|
:categories="chartData.backflows"
|
||||||
:completedNumber="backflowsCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -241,8 +231,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Curbing"
|
title="Curbing"
|
||||||
:todoNumber="chartData.curbing.todo"
|
:categories="chartData.curbing"
|
||||||
:completedNumber="chartData.curbing.done"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -264,8 +253,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Hydroseeding"
|
title="Hydroseeding"
|
||||||
:todoNumber="chartData.hydroseed.todo"
|
:categories="chartData.hydroseed"
|
||||||
:completedNumber="chartData.hydroseed.done"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -287,8 +275,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Machines"
|
title="Machines"
|
||||||
:todoNumber="machinesTodoNumber"
|
:categories="chartData.machines"
|
||||||
:completedNumber="machinesCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -310,8 +297,7 @@
|
||||||
<div class="widget-content">
|
<div class="widget-content">
|
||||||
<TodoChart
|
<TodoChart
|
||||||
title="Deliveries"
|
title="Deliveries"
|
||||||
:todoNumber="deliveriesTodoNumber"
|
:categories="chartData.deliveries"
|
||||||
:completedNumber="delivieriesCompletedNumber"
|
|
||||||
>
|
>
|
||||||
</TodoChart>
|
</TodoChart>
|
||||||
<button class="sidebar-button"
|
<button class="sidebar-button"
|
||||||
|
|
@ -326,7 +312,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from "vue";
|
import { ref, computed, onMounted, watch } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
//import Card from "primevue/card";
|
//import Card from "primevue/card";
|
||||||
import Card from "../common/Card.vue";
|
import Card from "../common/Card.vue";
|
||||||
|
|
@ -337,11 +323,14 @@ WateringSoil, Soil, Truck, SoilAlt } from "@iconoir/vue";
|
||||||
import Api from "../../api.js";
|
import Api from "../../api.js";
|
||||||
import DataUtils from "../../utils.js";
|
import DataUtils from "../../utils.js";
|
||||||
import { useNotificationStore } from "../../stores/notifications-primevue";
|
import { useNotificationStore } from "../../stores/notifications-primevue";
|
||||||
|
import { useCompanyStore } from "../../stores/company.js";
|
||||||
//import SimpleChart from "../common/SimpleChart.vue";
|
//import SimpleChart from "../common/SimpleChart.vue";
|
||||||
import TodoChart from "../common/TodoChart.vue";
|
import TodoChart from "../common/TodoChart.vue";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const defaultColors = ['blue', 'green', 'red'];
|
||||||
|
|
||||||
// Dummy data from utils
|
// Dummy data from utils
|
||||||
const clientData = ref(DataUtils.dummyClientData);
|
const clientData = ref(DataUtils.dummyClientData);
|
||||||
const jobData = ref(DataUtils.dummyJobData);
|
const jobData = ref(DataUtils.dummyJobData);
|
||||||
|
|
@ -355,13 +344,24 @@ const warrantyTodoNumber = ref(0);
|
||||||
const warrantyCompletedNumber = ref(10);
|
const warrantyCompletedNumber = ref(10);
|
||||||
|
|
||||||
const chartData = ref({
|
const chartData = ref({
|
||||||
locates: {todo: 0, done: 0},
|
locates: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
permits: {todo: 0, done: 0},
|
permits: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
curbing: {todo: 0, done: 0},
|
curbing: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
hydroseed: {todo: 0, done: 0},
|
hydroseed: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
permitFinalizations: {labels: ["Todo", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
warranties: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
bids: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
estimates: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
halfDown: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
fifteenDayFollowups: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
lateBalances: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
backflows: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
machines: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
|
deliveries: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
|
||||||
});
|
});
|
||||||
|
|
||||||
const notifications = useNotificationStore();
|
const notifications = useNotificationStore();
|
||||||
|
const companyStore = useCompanyStore();
|
||||||
|
|
||||||
// Computed values for dashboard metrics
|
// Computed values for dashboard metrics
|
||||||
const totalRevenue = computed(() => "$47,250");
|
const totalRevenue = computed(() => "$47,250");
|
||||||
|
|
@ -373,17 +373,26 @@ const avgResponseTime = computed(() => 2.3);
|
||||||
const navigateTo = (path) => {
|
const navigateTo = (path) => {
|
||||||
router.push(path);
|
router.push(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadChartData = async() => {
|
||||||
|
chartData.value.locates.data = await Api.getTasksDue("Locate", companyStore.currentCompany);
|
||||||
|
chartData.value.permits.data = await Api.getTasksDue("Permit", companyStore.currentCompany);
|
||||||
|
chartData.value.curbing.data = await Api.getTasksDue("Curbing", companyStore.currentCompany);
|
||||||
|
chartData.value.hydroseed.data = await Api.getTasksDue("Hydroseed", companyStore.currentCompany);
|
||||||
|
//Uncomment below when we can check if half-down payments have/can been paid
|
||||||
|
//chartData.value.estimates.data = await Api.getEstimatesHalfDownCount();
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(async() => {
|
onMounted(async() => {
|
||||||
notifications.addWarning("Dashboard metrics are based on dummy data for demonstration purposes. UPDATES COMING SOON!");
|
notifications.addWarning("Dashboard metrics are based on dummy data for demonstration purposes. UPDATES COMING SOON!");
|
||||||
chartData.value.locates.todo = await Api.getTasksDue("Locate");
|
await loadChartData();
|
||||||
chartData.value.locates.done = await Api.getTasksCompleted("Locate");
|
|
||||||
chartData.value.permits.todo = await Api.getTasksDue("Permit");
|
|
||||||
chartData.value.permits.done = await Api.getTasksCompleted("Permit");
|
|
||||||
chartData.value.curbing.todo = await Api.getTasksDue("Curbing");
|
|
||||||
chartData.value.curbing.done = await Api.getTasksCompleted("Curbing");
|
|
||||||
chartData.value.hydroseed.todo = await Api.getTasksDue("Hydroseed");
|
|
||||||
chartData.value.hydroseed.done = await Api.getTasksCompleted("Hydroseed");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(() => companyStore.currentCompany, async (newCompany, oldCompany) => {
|
||||||
|
console.log("Wathcing for new Company");
|
||||||
|
await loadChartData();
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue