added cancel button
This commit is contained in:
@@ -377,6 +377,7 @@ export default defineComponent({
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null as any,
|
||||
customer: {} as any,
|
||||
isLoading: false, // For main form submission
|
||||
isCardSaving: false, // For quick add card form
|
||||
quickGallonAmounts: [100, 125, 150, 175, 200, 220],
|
||||
@@ -384,6 +385,8 @@ export default defineComponent({
|
||||
promos: [] as Promo[],
|
||||
truckDriversList: [] as Driver[],
|
||||
pricingTiers: [] as PricingTier[],
|
||||
isLoadingAuthorize: true,
|
||||
authorizeCheck: { profile_exists: false, has_payment_methods: false, missing_components: [] as string[], valid_for_charging: false },
|
||||
isConfirmationModalVisible: false,
|
||||
formDelivery: {
|
||||
gallons_ordered: '',
|
||||
@@ -410,7 +413,7 @@ export default defineComponent({
|
||||
card_name: '',
|
||||
type_of_card: '',
|
||||
} as CardFormData,
|
||||
customer: {} as Customer,
|
||||
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
@@ -622,7 +625,29 @@ export default defineComponent({
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
async checkAuthorizeAccount() {
|
||||
if (!this.customer.id) return;
|
||||
|
||||
this.isLoadingAuthorize = true;
|
||||
|
||||
try {
|
||||
const path = `${import.meta.env.VITE_AUTHORIZE_URL}/user/check-authorize-account/${this.customer.id}`;
|
||||
const response = await axios.get(path, { headers: authHeader() });
|
||||
this.authorizeCheck = response.data;
|
||||
} catch (error) {
|
||||
console.error("Failed to check authorize account:", error);
|
||||
notify({ title: "Error", text: "Could not check payment account status.", type: "error" });
|
||||
// Set default error state
|
||||
this.authorizeCheck = {
|
||||
profile_exists: false,
|
||||
has_payment_methods: false,
|
||||
missing_components: ['api_error'],
|
||||
valid_for_charging: false
|
||||
};
|
||||
} finally {
|
||||
this.isLoadingAuthorize = false;
|
||||
}
|
||||
},
|
||||
async onCardSubmit() {
|
||||
this.v$.formCard.$validate();
|
||||
if (this.v$.formCard.$error) {
|
||||
@@ -643,13 +668,7 @@ export default defineComponent({
|
||||
name_on_card: this.formCard.card_name, // Map card_name to name_on_card for Flask
|
||||
};
|
||||
|
||||
// Payload for FastAPI backend (it only needs the essentials for Authorize.Net)
|
||||
const fastapiPayload = {
|
||||
card_number: this.formCard.card_number.replace(/\s/g, ''),
|
||||
expiration_date: `${this.formCard.expiration_year}-${this.formCard.expiration_month}`,
|
||||
cvv: this.formCard.security_number, // Map security_number to cvv for FastAPI
|
||||
main_card: false, // Send this to FastAPI as well
|
||||
};
|
||||
|
||||
|
||||
// --- STEP 2: CRITICAL CALL - SAVE CARD TO LOCAL DATABASE VIA FLASK ---
|
||||
try {
|
||||
@@ -671,6 +690,15 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
// --- STEP 3: BEST-EFFORT CALL - TOKENIZE CARD VIA FASTAPI ---
|
||||
if (this.authorizeCheck.profile_exists) {
|
||||
// Payload for FastAPI backend (it only needs the essentials for Authorize.Net)
|
||||
const fastapiPayload = {
|
||||
card_number: this.formCard.card_number.replace(/\s/g, ''),
|
||||
expiration_date: `${this.formCard.expiration_year}-${this.formCard.expiration_month}`,
|
||||
cvv: this.formCard.security_number, // Map security_number to cvv for FastAPI
|
||||
main_card: false, // Send this to FastAPI as well
|
||||
};
|
||||
|
||||
try {
|
||||
const fastapiPath = `${import.meta.env.VITE_AUTHORIZE_URL}/api/payments/customers/${this.customer.id}/cards`;
|
||||
console.log("Attempting to tokenize card with Authorize.Net via FastAPI:", fastapiPath);
|
||||
@@ -680,7 +708,9 @@ export default defineComponent({
|
||||
// If this fails, we just log it for the developers. We DON'T show an error to the user.
|
||||
console.warn("NON-CRITICAL-ERROR: Tokenization with Authorize.Net failed, but the card was saved locally.", error.response?.data || error.message);
|
||||
}
|
||||
|
||||
}else{
|
||||
console.log("Skipping Authorize.Net tokenization as no profile exists for customer.");
|
||||
}
|
||||
// --- STEP 4: ALWAYS SHOW SUCCESS, REFRESH CARDS, STAY ON PAGE ---
|
||||
// This code runs as long as the first (Flask) call was successful.
|
||||
notify({ type: 'success', title: 'Card Saved!' });
|
||||
|
||||
@@ -339,6 +339,13 @@
|
||||
<router-link :to="{ name: 'Ticket', params: { id: deliveryOrder.id } }">
|
||||
<button class="btn btn-success btn-sm">Print Ticket</button>
|
||||
</router-link>
|
||||
<button
|
||||
class="btn btn-error btn-sm"
|
||||
@click="cancelDelivery"
|
||||
v-if="[0, 2, 3, 4, 5, 9].includes(deliveryOrder.delivery_status)"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -527,6 +534,36 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
},
|
||||
cancelDelivery() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/cancel/' + this.deliveryOrder.id;
|
||||
axios({
|
||||
method: 'post',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "Delivery cancelled",
|
||||
type: "success",
|
||||
});
|
||||
// Refresh the delivery data
|
||||
this.getOilOrder(this.deliveryOrder.id);
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "Failed to cancel delivery",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
}).catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Error cancelling delivery",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
<th>Status</th>
|
||||
<th>Town / Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Options</th>
|
||||
<th>Payment</th>
|
||||
<th class="text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -79,13 +77,7 @@
|
||||
<span v-if="oil.emergency" class="badge badge-error badge-xs">EMERGENCY</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="oil.payment_type == 0">Cash</span>
|
||||
<span v-else-if="oil.payment_type == 1">CC</span>
|
||||
<span v-else-if="oil.payment_type == 2">Cash/CC</span>
|
||||
<span v-else-if="oil.payment_type == 3">Check</span>
|
||||
<span v-else-if="oil.payment_type == 4">Other</span>
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<router-link :to="{ name: 'deliveryOrder', params: { id: oil.id } }" class="btn btn-sm btn-ghost">View</router-link>
|
||||
@@ -137,13 +129,7 @@
|
||||
<span v-if="oil.customer_asked_for_fill" class="badge badge-info badge-xs">FILL</span>
|
||||
<span v-else>{{ oil.gallons_ordered }}</span>
|
||||
</p>
|
||||
<p><strong class="font-semibold">Payment:</strong>
|
||||
<span v-if="oil.payment_type == 0">Cash</span>
|
||||
<span v-else-if="oil.payment_type == 1">CC</span>
|
||||
<span v-else-if="oil.payment_type == 2">Cash/CC</span>
|
||||
<span v-else-if="oil.payment_type == 3">Check</span>
|
||||
<span v-else-if="oil.payment_type == 4">Other</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-actions justify-end flex-wrap gap-2 mt-2">
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<th>Status</th>
|
||||
<th>Town / Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Options</th>
|
||||
|
||||
<th class="text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
Reference in New Issue
Block a user