Working API CHARGING!

This commit is contained in:
2025-09-20 15:33:25 -04:00
parent b77e5b4b9d
commit 279f0d9deb
10 changed files with 1794 additions and 124 deletions

View File

@@ -51,13 +51,20 @@
<tbody>
<!-- Removed @click from tr to avoid conflicting actions -->
<tr v-for="service in services" :key="service.id" class=" hover:bg-blue-600">
<td class="align-top">{{ service.id }}</td>
<td class="align-top">
<td class="align-top text-white">{{ service.id }}</td>
<td class="align-top text-white">
<div>{{ formatDate(service.scheduled_date) }}</div>
<div class="text-xs opacity-70">{{ formatTime(service.scheduled_date) }}</div>
</td>
<td class="align-top">{{ service.customer_name }}</td>
<td class="align-top">{{ service.customer_address }}, {{ service.customer_town }}</td>
<td class="align-top">
<router-link
:to="{ name: 'customerProfile', params: { id: service.customer_id } }"
class="text-white hover:text-green-500 hover:underline"
>
{{ service.customer_name }}
</router-link>
</td>
<td class="align-top text-white">{{ service.customer_address }}, {{ service.customer_town }}</td>
<td class="align-top">
<span
class="badge badge-sm text-white"
@@ -66,7 +73,7 @@
{{ getServiceTypeName(service.type_service_call) }}
</span>
</td>
<td class="whitespace-normal text-sm align-top">
<td class="whitespace-normal text-sm align-top text-white">
<!-- TRUNCATION LOGIC FOR DESKTOP -->
<div v-if="!isLongDescription(service.description) || isExpanded(service.id)">
{{ service.description }}
@@ -77,10 +84,11 @@
<a @click.prevent="toggleExpand(service.id)" href="#" class="link link-info link-hover text-xs ml-1 whitespace-nowrap">Read more</a>
</div>
</td>
<td class="text-right font-mono align-top">{{ formatCurrency(service.service_cost) }}</td>
<td class="text-right font-mono align-top text-white">{{ formatCurrency(service.service_cost) }}</td>
<td class="text-right align-top space-x-2">
<button @click="openEditModal(service)" class="btn btn-sm btn-primary">View</button>
<router-link v-if="service.service_cost !== undefined && service.service_cost !== '' && Number(service.service_cost) === 0" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowChargeButton(service)" :to="{ name: 'payService', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowCaptureButton(service)" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-warning">Capture</router-link>
</td>
</tr>
</tbody>
@@ -93,7 +101,12 @@
<div class="card-body p-4">
<div class="flex justify-between items-start">
<div>
<h2 class="card-title text-base">{{ service.customer_name }}</h2>
<router-link
:to="{ name: 'customerProfile', params: { id: service.customer_id } }"
class="card-title text-base text-white hover:text-green-500 hover:underline"
>
{{ service.customer_name }}
</router-link>
<p class="text-xs text-gray-500">ID: {{ service.id }}</p>
<p class="text-xs text-gray-400">{{ service.customer_address }}, {{ service.customer_town }}</p>
</div>
@@ -122,7 +135,8 @@
<div class="card-actions justify-end mt-2 space-x-2">
<button @click="openEditModal(service)" class="btn btn-sm btn-primary">View</button>
<router-link v-if="service.service_cost !== undefined && service.service_cost !== '' && Number(service.service_cost) === 0" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowChargeButton(service)" :to="{ name: 'payService', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowCaptureButton(service)" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-warning">Capture</router-link>
</div>
</div>
</div>
@@ -160,6 +174,7 @@ interface ServiceCall {
type_service_call: number;
description: string;
service_cost: string;
payment_status?: number;
}
export default defineComponent({
@@ -189,7 +204,7 @@ export default defineComponent({
headers: authHeader(),
withCredentials: true,
});
this.services = response.data;
this.services = response.data.sort((a: ServiceCall, b: ServiceCall) => b.id - a.id);
} catch (error) {
console.error("Failed to fetch upcoming service calls:", error);
} finally {
@@ -313,6 +328,14 @@ export default defineComponent({
4: 'black',
};
return colorMap[typeId] || 'gray';
},
shouldShowChargeButton(service: any): boolean {
return service.payment_status === null || service.payment_status === undefined;
},
shouldShowCaptureButton(service: any): boolean {
return service.payment_status === 1;
}
},
})

View File

@@ -50,13 +50,20 @@
</thead>
<tbody>
<tr v-for="service in services" :key="service.id" class="hover:bg-blue-600">
<td class="align-top">{{ service.id }}</td>
<td class="align-top">
<td class="align-top text-white">{{ service.id }}</td>
<td class="align-top text-white">
<div>{{ formatDate(service.scheduled_date) }}</div>
<div class="text-xs opacity-70">{{ formatTime(service.scheduled_date) }}</div>
</td>
<td class="align-top">{{ service.customer_name }}</td>
<td class="align-top">{{ service.customer_address }}, {{ service.customer_town }}</td>
<td class="align-top">
<router-link
:to="{ name: 'customerProfile', params: { id: service.customer_id } }"
class="text-white hover:text-green-500 hover:underline"
>
{{ service.customer_name }}
</router-link>
</td>
<td class="align-top text-white">{{ service.customer_address }}, {{ service.customer_town }}</td>
<!--
FIX IS HERE: Replaced the colored text with a styled badge.
@@ -73,7 +80,7 @@
</span>
</td>
<td class="whitespace-normal text-sm align-top">
<td class="whitespace-normal text-sm align-top text-white">
<div v-if="!isLongDescription(service.description) || isExpanded(service.id)">
{{ service.description }}
<a v-if="isLongDescription(service.description)" @click.prevent="toggleExpand(service.id)" href="#" class="link link-info link-hover text-xs ml-1 whitespace-nowrap">Show less</a>
@@ -83,10 +90,11 @@
<a @click.prevent="toggleExpand(service.id)" href="#" class="link link-info link-hover text-xs ml-1 whitespace-nowrap">Read more</a>
</div>
</td>
<td class="text-right font-mono align-top">{{ formatCurrency(service.service_cost) }}</td>
<td class="text-right font-mono align-top text-white">{{ formatCurrency(service.service_cost) }}</td>
<td class="text-right align-top space-x-2">
<button @click="openEditModal(service)" class="btn btn-sm btn-primary">View</button>
<router-link v-if="service.service_cost !== undefined && service.service_cost !== '' && Number(service.service_cost) === 0" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowChargeButton(service)" :to="{ name: 'payService', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowCaptureButton(service)" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-warning">Capture</router-link>
</td>
</tr>
</tbody>
@@ -99,7 +107,12 @@
<div class="card-body p-4">
<div class="flex justify-between items-start">
<div>
<h2 class="card-title text-base">{{ service.customer_name }}</h2>
<router-link
:to="{ name: 'customerProfile', params: { id: service.customer_id } }"
class="card-title text-base text-white hover:text-green-500 hover:underline"
>
{{ service.customer_name }}
</router-link>
<p class="text-xs text-gray-500">ID: {{ service.id }}</p>
<p class="text-xs text-gray-400">{{ service.customer_address }}, {{ service.customer_town }}</p>
</div>
@@ -128,7 +141,8 @@
<div class="card-actions justify-end mt-2 space-x-2">
<button @click="openEditModal(service)" class="btn btn-sm btn-primary">View</button>
<router-link v-if="service.service_cost !== undefined && service.service_cost !== '' && Number(service.service_cost) === 0" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowChargeButton(service)" :to="{ name: 'payService', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowCaptureButton(service)" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-warning">Capture</router-link>
</div>
</div>
</div>
@@ -167,6 +181,7 @@ interface ServiceCall {
type_service_call: number;
description: string;
service_cost: string;
payment_status?: number;
}
export default defineComponent({
@@ -219,7 +234,7 @@ export default defineComponent({
headers: authHeader(),
withCredentials: true,
});
this.services = response.data;
this.services = response.data.sort((a: ServiceCall, b: ServiceCall) => b.id - a.id);
} catch (error) {
console.error("Failed to fetch past service calls:", error);
} finally {
@@ -326,6 +341,14 @@ export default defineComponent({
4: 'black',
};
return colorMap[typeId] || 'gray';
},
shouldShowChargeButton(service: any): boolean {
return service.payment_status === null || service.payment_status === undefined;
},
shouldShowCaptureButton(service: any): boolean {
return service.payment_status === 1;
}
},
})

View File

@@ -55,7 +55,14 @@
<div>{{ formatDate(service.scheduled_date) }}</div>
<div class="text-xs opacity-70">{{ formatTime(service.scheduled_date) }}</div>
</td>
<td class="align-top">{{ service.customer_name }}</td>
<td class="align-top">
<router-link
:to="{ name: 'customerProfile', params: { id: service.customer_id } }"
class="text-white hover:text-green-500 hover:underline"
>
{{ service.customer_name }}
</router-link>
</td>
<td class="align-top">{{ service.customer_address }}, {{ service.customer_town }}</td>
<!--
@@ -86,7 +93,8 @@
<td class="text-right font-mono align-top">{{ formatCurrency(service.service_cost) }}</td>
<td class="text-right align-top space-x-2">
<button @click="openEditModal(service)" class="btn btn-sm btn-primary">View</button>
<router-link v-if="service.service_cost !== undefined && service.service_cost !== '' && Number(service.service_cost) === 0" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowChargeButton(service)" :to="{ name: 'payService', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowCaptureButton(service)" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-warning">Capture</router-link>
</td>
</tr>
</tbody>
@@ -99,7 +107,12 @@
<div class="card-body p-4">
<div class="flex justify-between items-start">
<div>
<h2 class="card-title text-base">{{ service.customer_name }}</h2>
<router-link
:to="{ name: 'customerProfile', params: { id: service.customer_id } }"
class="card-title text-base text-white hover:text-green-500 hover:underline"
>
{{ service.customer_name }}
</router-link>
<p class="text-xs text-gray-500">ID: {{ service.id }}</p>
<p class="text-xs text-gray-400">{{ service.customer_address }}, {{ service.customer_town }}</p>
</div>
@@ -128,7 +141,8 @@
<div class="card-actions justify-end mt-2 space-x-2">
<button @click="openEditModal(service)" class="btn btn-sm btn-primary">View</button>
<router-link v-if="service.service_cost !== undefined && service.service_cost !== '' && Number(service.service_cost) === 0" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowChargeButton(service)" :to="{ name: 'payService', params: { id: service.id } }" class="btn btn-sm btn-success">Charge</router-link>
<router-link v-if="shouldShowCaptureButton(service)" :to="{ name: 'chargeServiceAuthorize', params: { id: service.id } }" class="btn btn-sm btn-warning">Capture</router-link>
</div>
</div>
</div>
@@ -167,6 +181,7 @@ interface ServiceCall {
type_service_call: number;
description: string;
service_cost: string;
payment_status?: number;
}
export default defineComponent({
@@ -219,7 +234,7 @@ export default defineComponent({
headers: authHeader(),
withCredentials: true,
});
this.services = response.data;
this.services = response.data.sort((a: ServiceCall, b: ServiceCall) => b.id - a.id);
} catch (error) {
console.error("Failed to fetch today's service calls:", error);
} finally {
@@ -326,6 +341,14 @@ export default defineComponent({
4: 'black',
};
return colorMap[typeId] || 'gray';
},
shouldShowChargeButton(service: any): boolean {
return service.payment_status === null || service.payment_status === undefined;
},
shouldShowCaptureButton(service: any): boolean {
return service.payment_status === 1;
}
},
})