working auto
This commit is contained in:
448
src/pages/automatic/view.vue
Normal file
448
src/pages/automatic/view.vue
Normal file
@@ -0,0 +1,448 @@
|
||||
<!-- src/pages/automatic/view.vue -->
|
||||
<template>
|
||||
<div class="flex">
|
||||
<!-- Main Content -->
|
||||
<div class="w-full px-4 md:px-10 py-4">
|
||||
<!-- Breadcrumbs & Title -->
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li><router-link :to="{ name: 'home' }">Home</router-link></li>
|
||||
<li><router-link :to="{ name: 'customer' }">Customers</router-link></li>
|
||||
<li v-if="customer && customer.id">
|
||||
<router-link :to="{ name: 'customerProfile', params: { id: customer.id } }">
|
||||
{{ customer.customer_first_name }} {{ customer.customer_last_name }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li>Automatic Delivery #{{ autoTicket.id }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h1 class="text-3xl font-bold mt-4 border-b border-gray-600 pb-2">
|
||||
Automatic Delivery #{{ autoTicket.id }}
|
||||
</h1>
|
||||
|
||||
<!-- TOP SECTION: Customer & Payment Status Info -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 my-6">
|
||||
<!-- Customer Info Card -->
|
||||
<div class="bg-neutral rounded-lg p-5">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div>
|
||||
<div class="text-xl font-bold">{{ autoTicket.customer_full_name }}</div>
|
||||
<div class="text-sm text-gray-400">Account: {{ autoTicket.account_number }}</div>
|
||||
</div>
|
||||
<router-link v-if="customer && customer.id" :to="{ name: 'customerProfile', params: { id: customer.id } }" class="btn btn-secondary btn-sm">
|
||||
View Profile
|
||||
</router-link>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ autoTicket.customer_address }}</div>
|
||||
<div v-if="autoTicket.customer_apt && autoTicket.customer_apt !== 'None'">Apt: {{ autoTicket.customer_apt }}</div>
|
||||
<div>
|
||||
{{ autoTicket.customer_town }},
|
||||
<span v-if="autoTicket.customer_state == 0">Massachusetts</span>
|
||||
<span v-else-if="autoTicket.customer_state == 1">Rhode Island</span>
|
||||
<span v-else-if="autoTicket.customer_state == 2">New Hampshire</span>
|
||||
<span v-else-if="autoTicket.customer_state == 3">Maine</span>
|
||||
<span v-else-if="autoTicket.customer_state == 4">Vermont</span>
|
||||
<span v-else-if="autoTicket.customer_state == 5">Connecticut</span>
|
||||
<span v-else-if="autoTicket.customer_state == 6">New York</span>
|
||||
<span v-else>Unknown state</span>
|
||||
{{ autoTicket.customer_zip }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-400 mt-1">
|
||||
Auto Delivery
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payment Status Card -->
|
||||
<div class="bg-neutral rounded-lg p-5">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="col-span-2">
|
||||
<div class="font-bold text-sm">Payment Status</div>
|
||||
<div class="badge badge-lg"
|
||||
:class="{
|
||||
'badge-success': autoTicket.payment_status == 3,
|
||||
'badge-info': autoTicket.payment_status == 1,
|
||||
'badge-error': autoTicket.payment_status == 0 || autoTicket.payment_status == null,
|
||||
'badge-warning': [2, 4].includes(autoTicket.payment_status)
|
||||
}">
|
||||
<span v-if="autoTicket.payment_status == 0 || autoTicket.payment_status == null">Unpaid</span>
|
||||
<span v-else-if="autoTicket.payment_status == 1">Pre-authorized</span>
|
||||
<span v-else-if="autoTicket.payment_status == 2">Processing</span>
|
||||
<span v-else-if="autoTicket.payment_status == 3">Paid</span>
|
||||
<span v-else-if="autoTicket.payment_status == 4">Failed</span>
|
||||
<span v-else>Unknown</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-bold text-sm">Fill Date</div>
|
||||
<div>{{ autoTicket.fill_date }}</div>
|
||||
</div>
|
||||
<div class="col-span-2">
|
||||
<div class="font-bold text-sm">Response Time</div>
|
||||
<div>Instant</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- BOTTOM SECTION: Auto Delivery & Financial Details -->
|
||||
<div class="bg-neutral rounded-lg p-6">
|
||||
<div class="grid grid-cols-1 xl:grid-cols-2 gap-8">
|
||||
<!-- Left Column: Pricing, Gallons, Transaction -->
|
||||
<div class="space-y-4">
|
||||
<!-- Gallons Delivered -->
|
||||
<div class="p-4 border rounded-md">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="label-text font-bold">Gallons Delivered</label>
|
||||
<div class="text-lg mt-1">
|
||||
<span>{{ autoTicket.gallons_delivered }} gallons</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pricing & Totals -->
|
||||
<div class="p-4 border rounded-md space-y-2">
|
||||
<label class="label-text font-bold">Financial Summary</label>
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<span>Total Amount</span>
|
||||
<span>${{ autoTicket.total_amount_customer }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-lg font-bold">
|
||||
Estimated Charge Amount
|
||||
</span>
|
||||
<span class="text-2xl font-bold text-success">
|
||||
${{ autoTicket.total_amount_customer }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Transaction Summary -->
|
||||
<div v-if="autoTicket.payment_type == 11" class="p-4 border rounded-md">
|
||||
<label class="label-text font-bold">Authorize.net Transaction Details</label>
|
||||
<div v-if="transaction" class="mt-2 space-y-2">
|
||||
<div class="flex justify-between">
|
||||
<span class="font-bold">Transaction ID:</span>
|
||||
<span class="font-mono">{{ transaction.auth_net_transaction_id || 'N/A' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Pre-Auth Amount:</span>
|
||||
<span>${{ transaction.preauthorize_amount || '0.00' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Charge Amount:</span>
|
||||
<span>${{ transaction.charge_amount || '0.00' }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Type:</span>
|
||||
<span :class="getTypeColor(transaction.transaction_type)">
|
||||
{{ transaction.transaction_type === 0 ? 'Charge' : transaction.transaction_type === 1 ? 'Auth' : transaction.transaction_type === 2 ? 'Capture' : 'Other' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Date:</span>
|
||||
<span>{{ format_date(transaction.created_at) }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Status:</span>
|
||||
<span :class="transaction.status === 0 ? 'text-success' : 'text-error'">
|
||||
{{ transaction.status === 0 ? 'Approved' : 'Declined' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="mt-2 text-gray-500">
|
||||
No authorize.net transaction data available
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Simple Payment Display -->
|
||||
<div v-else class="p-4 border rounded-md">
|
||||
<label class="label-text font-bold">Payment Method</label>
|
||||
<div class="mt-2">
|
||||
<span class="text-info font-semibold">{{ getPaymentMethodName(autoTicket.payment_type) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delivery Summary -->
|
||||
<div class="p-4 border rounded-md">
|
||||
<label class="label-text font-bold">Delivery Summary</label>
|
||||
<div class="space-y-2 mt-2">
|
||||
<div class="flex justify-between">
|
||||
<span>Gallons Delivered:</span>
|
||||
<span class="font-semibold">{{ autoTicket.gallons_delivered }} gallons</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>Price per Gallon:</span>
|
||||
<span class="font-semibold">${{ autoTicket.price_per_gallon }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between font-bold">
|
||||
<span>Total:</span>
|
||||
<span>${{ autoTicket.total_amount_customer }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column -->
|
||||
<div class="space-y-4">
|
||||
<!-- Payment Method -->
|
||||
<div class="p-4 border rounded-md">
|
||||
<label class="label-text font-bold">Payment Method</label>
|
||||
<div class="mt-1">
|
||||
<div class="text-lg">
|
||||
{{ getPaymentMethodName(autoTicket.payment_type) }}
|
||||
</div>
|
||||
|
||||
<!-- Card display -->
|
||||
<div v-if="userCardfound && [1, 2, 3].includes(autoTicket.payment_type)"
|
||||
class="p-4 rounded-lg border mt-2"
|
||||
:class="userCard.main_card ? 'bg-primary/10 border-primary' : 'bg-base-200 border-base-300'">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<div class="font-bold">{{ userCard.name_on_card }}</div>
|
||||
<div class="text-xs opacity-70">{{ userCard.type_of_card }}</div>
|
||||
</div>
|
||||
<div v-if="userCard.main_card" class="badge badge-primary badge-sm">Primary</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 text-sm font-mono tracking-wider">
|
||||
<p>{{ userCard.card_number }}</p>
|
||||
<p>
|
||||
Exp:
|
||||
<span v-if="Number(userCard.expiration_month) < 10">0</span>{{ userCard.expiration_month }} / {{ userCard.expiration_year }}
|
||||
</p>
|
||||
<p>CVV: {{ userCard.security_number }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notes -->
|
||||
<div class="p-4 border rounded-md">
|
||||
<label class="label-text font-bold">Notes</label>
|
||||
<div class="prose prose-sm mt-4 max-w-none">
|
||||
<blockquote class="text-gray-400">Auto delivery processed automatically based on tank levels.</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
|
||||
interface UserCard {
|
||||
id: number;
|
||||
last_four: string;
|
||||
type_of_card: string;
|
||||
expiration_month: number;
|
||||
expiration_year: number;
|
||||
name_on_card: string;
|
||||
card_number: string;
|
||||
security_number: string;
|
||||
main_card?: boolean;
|
||||
}
|
||||
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import { notify } from "@kyvg/vue3-notification"
|
||||
import moment from 'moment';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'automaticDeliveryView',
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
autoTicket: {
|
||||
id: 0,
|
||||
customer_id: 0,
|
||||
account_number: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_address: '',
|
||||
customer_zip: '',
|
||||
customer_full_name: '',
|
||||
customer_apt: '',
|
||||
fill_date: '',
|
||||
oil_prices_id: 0,
|
||||
gallons_delivered: '',
|
||||
price_per_gallon: '',
|
||||
total_amount_customer: '',
|
||||
payment_type: 0,
|
||||
payment_card_id: null,
|
||||
payment_status: null,
|
||||
open_ticket_id: null,
|
||||
} as any,
|
||||
autoDelivery: {
|
||||
id: 0,
|
||||
customer_id: 0,
|
||||
account_number: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_address: '',
|
||||
customer_zip: '',
|
||||
customer_full_name: '',
|
||||
last_fill: '',
|
||||
days_since_last_fill: 0,
|
||||
last_updated: '',
|
||||
estimated_gallons_left: 0,
|
||||
estimated_gallons_left_prev_day: 0,
|
||||
tank_height: '',
|
||||
tank_size: '',
|
||||
house_factor: 0,
|
||||
auto_status: 0,
|
||||
open_ticket_id: null,
|
||||
},
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_address: '',
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
},
|
||||
transaction: null as any,
|
||||
userCardfound: false,
|
||||
userCard: {} as UserCard,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.getAutoTicket(this.$route.params.id);
|
||||
},
|
||||
|
||||
methods: {
|
||||
format_date(value: string) {
|
||||
if (value) {
|
||||
return moment(String(value)).format('LLLL')
|
||||
}
|
||||
},
|
||||
getTypeColor(transactionType: number) {
|
||||
switch (transactionType) {
|
||||
case 1: return 'text-blue-600'; // Auth
|
||||
case 0: return 'text-orange-600'; // Charge
|
||||
case 2: return 'text-purple-600'; // Capture
|
||||
default: return 'text-gray-600';
|
||||
}
|
||||
},
|
||||
|
||||
getPaymentMethodName(paymentType: number): string {
|
||||
switch (paymentType) {
|
||||
case 0: return 'Cash';
|
||||
case 1: return 'Credit Card';
|
||||
case 11: return 'Authorize.net PCI Card API';
|
||||
default: return 'Other';
|
||||
}
|
||||
},
|
||||
|
||||
getCustomer(customerId: number) {
|
||||
if (!customerId) return;
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/customer/${customerId}`;
|
||||
axios.get(path, { withCredentials: true })
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error("Error fetching customer:", error);
|
||||
});
|
||||
},
|
||||
|
||||
getPaymentCard(cardId: any) {
|
||||
if (!cardId) {
|
||||
this.userCardfound = false;
|
||||
return;
|
||||
}
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/payment/card/${cardId}`;
|
||||
axios.get(path, { withCredentials: true })
|
||||
.then((response: any) => {
|
||||
if (response.data && response.data.card_number && response.data.card_number !== '') {
|
||||
this.userCard = response.data;
|
||||
this.userCardfound = true;
|
||||
} else {
|
||||
this.userCard = {} as UserCard;
|
||||
this.userCardfound = false;
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
this.userCard = {} as UserCard;
|
||||
this.userCardfound = false;
|
||||
});
|
||||
},
|
||||
|
||||
getAutoTicket(autoTicketId: any) {
|
||||
if (!autoTicketId) return;
|
||||
const path = `${import.meta.env.VITE_AUTO_URL}/delivery/autoticket/${autoTicketId}`;
|
||||
axios.get(path, { withCredentials: true })
|
||||
.then((response: any) => {
|
||||
this.autoTicket = response.data;
|
||||
this.getCustomer(this.autoTicket.customer_id);
|
||||
if ([1, 2, 3].includes(this.autoTicket.payment_type)) {
|
||||
this.getPaymentCard(this.autoTicket.payment_card_id);
|
||||
}
|
||||
if (this.autoTicket.payment_type == 11) {
|
||||
this.getTransaction(autoTicketId);
|
||||
}
|
||||
this.getAutoDelivery(autoTicketId);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not get automatic ticket",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getAutoDelivery(ticketId: any) {
|
||||
const path = `${import.meta.env.VITE_AUTO_URL}/delivery/finddelivery/${ticketId}`;
|
||||
axios.get(path, { withCredentials: true })
|
||||
.then((response: any) => {
|
||||
this.autoDelivery = response.data;
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error("Error fetching auto delivery:", error);
|
||||
});
|
||||
},
|
||||
|
||||
getTransaction(deliveryId: any) {
|
||||
const path = `${import.meta.env.VITE_AUTHORIZE_URL}/api/auto/transaction/delivery/${deliveryId}`;
|
||||
console.log(path)
|
||||
axios.get(path, { withCredentials: true, headers: authHeader() })
|
||||
.then((response: any) => {
|
||||
this.transaction = response.data;
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error("No transaction found for delivery:", error);
|
||||
this.transaction = null;
|
||||
});
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user