small frontend changed
This commit is contained in:
@@ -137,9 +137,10 @@ const getSourceText = (transaction: Transaction) => {
|
|||||||
const formatDate = (dateStr: string) => dateStr.split('T')[0]; // YYYY-MM-DD
|
const formatDate = (dateStr: string) => dateStr.split('T')[0]; // YYYY-MM-DD
|
||||||
const getTypeColor = (transactionType: number) => {
|
const getTypeColor = (transactionType: number) => {
|
||||||
switch (transactionType) {
|
switch (transactionType) {
|
||||||
case 1: return 'text-blue-600';
|
case 1: return 'text-blue-600'; // Auth
|
||||||
case 0: return 'text-orange-600';
|
case 0: return 'text-orange-600'; // Charge
|
||||||
case 2: return 'text-green-600';
|
case 2: return 'text-purple-600'; // Capture
|
||||||
|
case 3: return 'text-green-600'; // Delivery/Other
|
||||||
default: return 'text-gray-600';
|
default: return 'text-gray-600';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -334,7 +334,6 @@ export default defineComponent({
|
|||||||
console.log(`[DEBUG] Component Mounted. Fetching data for delivery ID: ${deliveryId}`);
|
console.log(`[DEBUG] Component Mounted. Fetching data for delivery ID: ${deliveryId}`);
|
||||||
this.getOilOrder(deliveryId);
|
this.getOilOrder(deliveryId);
|
||||||
this.getOilPricing();
|
this.getOilPricing();
|
||||||
this.getTransaction(deliveryId);
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getOilOrder(delivery_id: any) {
|
async getOilOrder(delivery_id: any) {
|
||||||
@@ -364,6 +363,9 @@ export default defineComponent({
|
|||||||
if ([1, 2].includes(this.deliveryOrder.payment_type) && this.deliveryOrder.payment_card_id) {
|
if ([1, 2].includes(this.deliveryOrder.payment_type) && this.deliveryOrder.payment_card_id) {
|
||||||
this.getPaymentCard(this.deliveryOrder.payment_card_id);
|
this.getPaymentCard(this.deliveryOrder.payment_card_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call transaction fetch after customer is loaded
|
||||||
|
setTimeout(() => this.getTransaction(delivery_id), 500);
|
||||||
} else {
|
} else {
|
||||||
console.error('[DEBUG] getOilOrder response was not OK or data is missing.');
|
console.error('[DEBUG] getOilOrder response was not OK or data is missing.');
|
||||||
notify({ title: "Data Error", text: "Could not retrieve complete delivery details.", type: "error" });
|
notify({ title: "Data Error", text: "Could not retrieve complete delivery details.", type: "error" });
|
||||||
@@ -410,27 +412,63 @@ export default defineComponent({
|
|||||||
.catch((error: any) => { console.error("[DEBUG] Error fetching oil pricing:", error); });
|
.catch((error: any) => { console.error("[DEBUG] Error fetching oil pricing:", error); });
|
||||||
},
|
},
|
||||||
getTransaction(delivery_id: any) {
|
getTransaction(delivery_id: any) {
|
||||||
const path = `${import.meta.env.VITE_AUTHORIZE_URL}/api/transaction/delivery/${delivery_id}`;
|
// Consistent with delivery/view.vue - use customer transaction endpoint
|
||||||
axios.get(path, { withCredentials: true, headers: authHeader() })
|
if (this.customer && this.customer.id) {
|
||||||
.then((response: any) => {
|
const path = `${import.meta.env.VITE_BASE_URL}/payment/transactions/customer/${this.customer.id}/1`;
|
||||||
this.transaction = response.data;
|
axios.get(path, { withCredentials: true, headers: authHeader() })
|
||||||
})
|
.then((response: any) => {
|
||||||
.catch((error: any) => {
|
console.log("Transaction API response:", response.data);
|
||||||
// Handle 404 gracefully - delivery doesn't have transaction data in authorize system
|
// Handle both single transaction object and array responses
|
||||||
if (error.response && error.response.status === 404) {
|
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
|
||||||
console.log(`No transaction found for delivery ${delivery_id} in authorize system`);
|
// Find the transaction for this specific delivery
|
||||||
this.transaction = null;
|
const deliveryTransaction = response.data.find((txn: any) =>
|
||||||
} else {
|
txn.delivery_id === parseInt(delivery_id) ||
|
||||||
console.error("Error fetching transaction:", error);
|
txn.transaction_id === delivery_id ||
|
||||||
this.transaction = null;
|
txn.delivery_number === delivery_id
|
||||||
}
|
);
|
||||||
});
|
this.transaction = deliveryTransaction || null;
|
||||||
|
} else if (response.data && !Array.isArray(response.data)) {
|
||||||
|
// If single transaction, check if it's for this delivery
|
||||||
|
const txn = response.data;
|
||||||
|
if (txn.delivery_id === parseInt(delivery_id) ||
|
||||||
|
txn.transaction_id === delivery_id ||
|
||||||
|
txn.delivery_number === delivery_id) {
|
||||||
|
this.transaction = txn;
|
||||||
|
} else {
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.transaction) {
|
||||||
|
console.log(`No transaction found for delivery ${delivery_id} among customer transactions`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
// Handle various error responses gracefully
|
||||||
|
if (error.response && error.response.status === 404) {
|
||||||
|
console.log(`No transactions found for customer ${this.customer.id}`);
|
||||||
|
this.transaction = null;
|
||||||
|
} else if (error.response && error.response.status === 400) {
|
||||||
|
console.log(`Bad request for customer transactions: ${error.response.data?.detail || error.message}`);
|
||||||
|
this.transaction = null;
|
||||||
|
} else {
|
||||||
|
console.error("Error fetching transaction:", error);
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log("Customer data not available, cannot fetch transactions");
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getTypeColor(transactionType: number) {
|
getTypeColor(transactionType: number) {
|
||||||
switch (transactionType) {
|
switch (transactionType) {
|
||||||
case 1: return 'text-blue-600';
|
case 1: return 'text-blue-600'; // Auth
|
||||||
case 0: return 'text-orange-600';
|
case 0: return 'text-orange-600'; // Charge
|
||||||
case 2: return 'text-green-600';
|
case 2: return 'text-purple-600'; // Capture
|
||||||
|
case 3: return 'text-green-600'; // Delivery/Other
|
||||||
default: return 'text-gray-600';
|
default: return 'text-gray-600';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -458,36 +496,15 @@ export default defineComponent({
|
|||||||
if (!finalizeResponse.data.ok) {
|
if (!finalizeResponse.data.ok) {
|
||||||
throw new Error(finalizeResponse.data.error || "Failed to update delivery details.");
|
throw new Error(finalizeResponse.data.error || "Failed to update delivery details.");
|
||||||
}
|
}
|
||||||
if ([1, 2].includes(this.deliveryOrder.payment_type)) {
|
|
||||||
const transactionUrl = `${import.meta.env.VITE_AUTHORIZE_URL}/api/transaction/delivery/${this.deliveryOrder.id}`;
|
|
||||||
try {
|
|
||||||
const transactionResponse = await axios.get(transactionUrl, { withCredentials: true, headers: authHeader() });
|
|
||||||
const preAuthTx = transactionResponse.data as PreAuthTransaction;
|
|
||||||
if (preAuthTx && preAuthTx.transaction_type === 1 && preAuthTx.status === 0) {
|
|
||||||
const capturePayload = {
|
|
||||||
auth_net_transaction_id: preAuthTx.auth_net_transaction_id,
|
|
||||||
charge_amount: this.finalChargeAmount.toFixed(2),
|
|
||||||
};
|
|
||||||
const capturePath = `${import.meta.env.VITE_AUTHORIZE_URL}/api/capture/`;
|
|
||||||
await axios.post(capturePath, capturePayload, { withCredentials: true, headers: authHeader() });
|
|
||||||
notify({ title: "Payment Captured", text: `Successfully charged $${capturePayload.charge_amount}.`, type: "success" });
|
|
||||||
} else {
|
|
||||||
notify({ title: "Warning", text: "No valid pre-authorization found to capture. Please charge manually.", type: "warn" });
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
if (error.response?.status === 404 && error.response?.data?.detail?.includes("No pre-authorization transaction found")) {
|
|
||||||
notify({ title: "Redirecting", text: "No pre-authorization found. Redirecting to customer profile to update payment method.", type: "info" });
|
|
||||||
this.$router.push({ name: "customerProfile", params: { id: this.customer.id } });
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
notify({ title: "Error", text: "Failed to check transaction status.", type: "error" });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.CreateTransaction();
|
this.CreateTransaction();
|
||||||
notify({ title: "Success", text: "Ticket has been finalized.", type: "success" });
|
notify({ title: "Success", text: "Ticket has been finalized.", type: "success" });
|
||||||
this.$router.push({ name: "deliveryOrder", params: { id: this.deliveryOrder.id } });
|
|
||||||
|
// Redirect based on payment type - redirect to capture for credit card payments
|
||||||
|
if ([1, 2].includes(this.deliveryOrder.payment_type)) {
|
||||||
|
this.$router.push({ name: "captureAuthorize", params: { id: this.deliveryOrder.id } });
|
||||||
|
} else {
|
||||||
|
this.$router.push({ name: "deliveryOrder", params: { id: this.deliveryOrder.id } });
|
||||||
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorMessage = error.response?.data?.detail || "An error occurred during finalization.";
|
const errorMessage = error.response?.data?.detail || "An error occurred during finalization.";
|
||||||
notify({ title: "Error", text: errorMessage, type: "error" });
|
notify({ title: "Error", text: errorMessage, type: "error" });
|
||||||
|
|||||||
@@ -145,7 +145,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Transaction Summary -->
|
<!-- Transaction Summary -->
|
||||||
<div v-if="transaction && transaction.auth_net_transaction_id" class="p-4 border rounded-md">
|
<div v-if="transaction && (transaction.transaction_type !== undefined || transaction.preauthorize_amount || transaction.charge_amount)" class="p-4 border rounded-md">
|
||||||
<label class="label-text font-bold">Transaction Summary</label>
|
<label class="label-text font-bold">Transaction Summary</label>
|
||||||
<div class="mt-2 space-y-2">
|
<div class="mt-2 space-y-2">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
@@ -448,7 +448,6 @@ export default defineComponent({
|
|||||||
this.getOilOrderMoney(this.$route.params.id);
|
this.getOilOrderMoney(this.$route.params.id);
|
||||||
this.sumdelivery(this.$route.params.id);
|
this.sumdelivery(this.$route.params.id);
|
||||||
this.getOilPricing();
|
this.getOilPricing();
|
||||||
this.getTransaction(this.$route.params.id);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -459,9 +458,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
getTypeColor(transactionType: number) {
|
getTypeColor(transactionType: number) {
|
||||||
switch (transactionType) {
|
switch (transactionType) {
|
||||||
case 1: return 'text-blue-600';
|
case 1: return 'text-blue-600'; // Auth
|
||||||
case 0: return 'text-orange-600';
|
case 0: return 'text-orange-600'; // Charge
|
||||||
case 2: return 'text-green-600';
|
case 2: return 'text-green-600'; // Capture
|
||||||
|
case 3: return 'text-purple-600'; // Delivery/Other
|
||||||
default: return 'text-gray-600';
|
default: return 'text-gray-600';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -522,22 +522,26 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
getCustomer(user_id: any) {
|
getCustomer(user_id: any) {
|
||||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
return new Promise((resolve, reject) => {
|
||||||
axios({
|
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||||
method: "get",
|
axios({
|
||||||
url: path,
|
method: "get",
|
||||||
withCredentials: true,
|
url: path,
|
||||||
})
|
withCredentials: true,
|
||||||
.then((response: any) => {
|
|
||||||
this.customer = response.data;
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.then((response: any) => {
|
||||||
|
this.customer = response.data;
|
||||||
|
resolve(response.data);
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
notify({
|
notify({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
text: "Could not find customer",
|
text: "Could not find customer",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
|
reject(error);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getPaymentCard(card_id: any) {
|
getPaymentCard(card_id: any) {
|
||||||
@@ -568,40 +572,45 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getOilOrder(delivery_id: any) {
|
async getOilOrder(delivery_id: any) {
|
||||||
if (!delivery_id) { // Add a guard to prevent calls with an undefined ID
|
if (!delivery_id) { // Add a guard to prevent calls with an undefined ID
|
||||||
console.error("getOilOrder called with no ID.");
|
console.error("getOilOrder called with no ID.");
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/" + delivery_id;
|
|
||||||
axios({
|
|
||||||
method: "get",
|
|
||||||
url: path,
|
|
||||||
withCredentials: true,
|
|
||||||
headers: authHeader(),
|
|
||||||
})
|
|
||||||
.then((response: any) => {
|
|
||||||
// FIX: Check for the 'ok' flag and access the nested 'delivery' object
|
|
||||||
if (response.data && response.data.ok) {
|
|
||||||
this.deliveryOrder = response.data.delivery; // <-- THIS IS THE CRITICAL CHANGE
|
|
||||||
|
|
||||||
// Now that this.deliveryOrder is the correct object, the rest of the logic will work.
|
|
||||||
this.getCustomer(this.deliveryOrder.customer_id);
|
|
||||||
|
|
||||||
if ([1, 2, 3].includes(this.deliveryOrder.payment_type)) {
|
|
||||||
this.getPaymentCard(this.deliveryOrder.payment_card_id);
|
|
||||||
}
|
}
|
||||||
if (this.deliveryOrder.promo_id != null) {
|
let path = import.meta.env.VITE_BASE_URL + "/delivery/" + delivery_id;
|
||||||
this.getPromo(this.deliveryOrder.promo_id);
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
method: "get",
|
||||||
|
url: path,
|
||||||
|
withCredentials: true,
|
||||||
|
headers: authHeader(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// FIX: Check for the 'ok' flag and access the nested 'delivery' object
|
||||||
|
if (response.data && response.data.ok) {
|
||||||
|
this.deliveryOrder = response.data.delivery; // <-- THIS IS THE CRITICAL CHANGE
|
||||||
|
|
||||||
|
// Now that this.deliveryOrder is the correct object, the rest of the logic will work.
|
||||||
|
await this.getCustomer(this.deliveryOrder.customer_id);
|
||||||
|
|
||||||
|
if ([1, 2, 3].includes(this.deliveryOrder.payment_type)) {
|
||||||
|
this.getPaymentCard(this.deliveryOrder.payment_card_id);
|
||||||
|
}
|
||||||
|
if (this.deliveryOrder.promo_id != null) {
|
||||||
|
this.getPromo(this.deliveryOrder.promo_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that customer is loaded, we can fetch transactions directly
|
||||||
|
this.getTransaction(delivery_id);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error("API Error:", response.data.error || "Failed to fetch delivery data.");
|
||||||
|
notify({ title: "Error", text: "Could not load delivery details.", type: "error" });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching delivery order:", error);
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
console.error("API Error:", response.data.error || "Failed to fetch delivery data.");
|
|
||||||
notify({ title: "Error", text: "Could not load delivery details.", type: "error" });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch( console.log("")
|
|
||||||
);
|
|
||||||
},
|
|
||||||
getOilOrderMoney(delivery_id: any) {
|
getOilOrderMoney(delivery_id: any) {
|
||||||
let path = import.meta.env.VITE_MONEY_URL + "/delivery/order/money/" + delivery_id;
|
let path = import.meta.env.VITE_MONEY_URL + "/delivery/order/money/" + delivery_id;
|
||||||
axios({
|
axios({
|
||||||
@@ -709,22 +718,57 @@ getOilOrder(delivery_id: any) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getTransaction(delivery_id: any) {
|
getTransaction(delivery_id: any) {
|
||||||
const path = `${import.meta.env.VITE_AUTHORIZE_URL}/api/transaction/delivery/${delivery_id}`;
|
// Fix: Use customer transaction endpoint to get transactions for this delivery's customer
|
||||||
axios.get(path, { withCredentials: true, headers: authHeader() })
|
// The API seems to work with customer-centric endpoints
|
||||||
.then((response: any) => {
|
if (this.customer && this.customer.id) {
|
||||||
console.log("Transaction API response:", response.data); // Debug log to see actual response structure
|
const path = `${import.meta.env.VITE_BASE_URL}/payment/transactions/customer/${this.customer.id}/1`;
|
||||||
this.transaction = response.data;
|
axios.get(path, { withCredentials: true, headers: authHeader() })
|
||||||
})
|
.then((response: any) => {
|
||||||
.catch((error: any) => {
|
console.log("Transaction API response:", response.data); // Debug log to see actual response structure
|
||||||
// Handle 404 gracefully - delivery doesn't have transaction data in authorize system
|
// Handle both single transaction object and array responses
|
||||||
if (error.response && error.response.status === 404) {
|
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
|
||||||
console.log(`No transaction found for delivery ${delivery_id} in authorize system`);
|
// Find the transaction for this specific delivery
|
||||||
this.transaction = null;
|
const deliveryTransaction = response.data.find((txn: any) =>
|
||||||
} else {
|
txn.delivery_id === parseInt(delivery_id) ||
|
||||||
console.error("Error fetching transaction:", error);
|
txn.transaction_id === delivery_id ||
|
||||||
this.transaction = null;
|
txn.delivery_number === delivery_id
|
||||||
}
|
);
|
||||||
});
|
this.transaction = deliveryTransaction || null;
|
||||||
|
} else if (response.data && !Array.isArray(response.data)) {
|
||||||
|
// If single transaction, check if it's for this delivery
|
||||||
|
const txn = response.data;
|
||||||
|
if (txn.delivery_id === parseInt(delivery_id) ||
|
||||||
|
txn.transaction_id === delivery_id ||
|
||||||
|
txn.delivery_number === delivery_id) {
|
||||||
|
this.transaction = txn;
|
||||||
|
} else {
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.transaction) {
|
||||||
|
console.log(`No transaction found for delivery ${delivery_id} among customer transactions`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
// Handle various error responses gracefully
|
||||||
|
if (error.response && error.response.status === 404) {
|
||||||
|
console.log(`No transactions found for customer ${this.customer.id}`);
|
||||||
|
this.transaction = null;
|
||||||
|
} else if (error.response && error.response.status === 400) {
|
||||||
|
console.log(`Bad request for customer transactions: ${error.response.data?.detail || error.message}`);
|
||||||
|
this.transaction = null;
|
||||||
|
} else {
|
||||||
|
console.error("Error fetching transaction:", error);
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log("Customer data not available, cannot fetch transactions");
|
||||||
|
this.transaction = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -159,7 +159,7 @@
|
|||||||
<div class="bg-base-100 rounded-lg p-5">
|
<div class="bg-base-100 rounded-lg p-5">
|
||||||
<h2 class="text-2xl font-bold mb-4">Gallons Delivered</h2>
|
<h2 class="text-2xl font-bold mb-4">Gallons Delivered</h2>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<div class="text-4xl font-bold text-primary">{{ gallonsDelivered || '0.00' }}</div>
|
<div class="text-4xl font-bold text-success">{{ gallonsDelivered || '0.00' }}</div>
|
||||||
<div class="text-sm opacity-70">gallons</div>
|
<div class="text-sm opacity-70">gallons</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -392,9 +392,14 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
notify({ title: "Error", text: "No pre-authorized transaction found", type: "error" });
|
if (error.response && error.response.status === 404) {
|
||||||
console.error("Error fetching transaction:", error);
|
notify({ title: "Info", text: "No pre-authorization found. Redirecting to customer profile to update payment method.", type: "info" });
|
||||||
this.$router.push({ name: 'finalizeTicket', params: { id: this.$route.params.id } });
|
console.log("No transaction found for delivery - redirecting to customer profile");
|
||||||
|
this.$router.push({ name: 'customerProfile', params: { id: this.customer.id } });
|
||||||
|
} else {
|
||||||
|
notify({ title: "Error", text: "No pre-authorized transaction found", type: "error" });
|
||||||
|
this.$router.push({ name: 'finalizeTicket', params: { id: this.$route.params.id } });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user