-
-
+
+
+
+
+
+
+
Today's Price Per Gallon
+
+
+
+
+ | Gallons |
+ Total Price |
+
+
+
+
+ | {{ tier.gallons }} |
+ ${{ Number(tier.price).toFixed(2) }} |
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
Credit Cards
+
+
+
-
-
-
-
+
+
+
+
+
+
{{ card.name_on_card }}
+
{{ card.type_of_card }}
+
+
Primary
+
+
+
{{ card.card_number }}
+
Exp: 0{{ card.expiration_month }} / {{ card.expiration_year }}
+
CVV: {{ card.security_number }}
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -158,13 +248,14 @@ 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 { required, minLength } from "@vuelidate/validators";
+import { required, minLength, requiredIf } from "@vuelidate/validators";
import { notify } from "@kyvg/vue3-notification";
// Interfaces to describe the shape of your data
interface Customer { account_number: string; id: number; customer_first_name: string; customer_last_name: string; customer_address: string; customer_apt: string; customer_town: string; customer_state: number; customer_zip: string; customer_phone_number: string; }
interface DeliveryOrder { id: string; customer_id: number; payment_type: number; payment_card_id: number; gallons_ordered: number; customer_asked_for_fill: boolean | number; delivery_status: number; driver_employee_id: number; promo_id: number; expected_delivery_date: string; when_ordered: string; prime: boolean | number; emergency: boolean | number; same_day: boolean | number; dispatcher_notes: string; }
-interface UserCard { id: number; type_of_card: string; card_number: string; name_on_card: string; expiration_month: string; expiration_year: string; last_four_digits: string; security_number: string; }
+interface UserCard { id: number; type_of_card: string; card_number: string; name_on_card: string; expiration_month: number; expiration_year: number; last_four_digits: string; security_number: string; main_card: boolean; }
+interface PricingTier { gallons: number; price: string | number; }
const STATE_MAP: { [key: number]: string } = { 0: 'Massachusetts', 1: 'Rhode Island', 2: 'New Hampshire', 3: 'Maine', 4: 'Vermont', 5: 'Connecticut', 6: 'New York' };
@@ -174,10 +265,12 @@ export default defineComponent({
data() {
return {
v$: useValidate(),
+ quickGallonAmounts: [100, 125, 150, 175, 200, 220],
deliveryStatus: [] as any[],
truckDriversList: [] as any[],
userCards: [] as UserCard[],
promos: [] as any[],
+ pricingTiers: [] as PricingTier[],
customer: {} as Customer,
deliveryOrder: {} as DeliveryOrder,
userCard: {} as UserCard,
@@ -197,6 +290,10 @@ export default defineComponent({
promo_id: 0,
payment_type: 0,
credit_card_id: 0,
+ credit: false,
+ cash: false,
+ check: false,
+ other: false,
},
},
}
@@ -206,11 +303,31 @@ export default defineComponent({
return {
CreateOilOrderForm: {
basicInfo: {
- gallons_ordered: { required, minLength: minLength(1) },
- // RESTORED: Add validation for expected date
+ gallons_ordered: {
+ required: requiredIf(function(this: any) {
+ return !this.CreateOilOrderForm.basicInfo.customer_asked_for_fill;
+ }),
+ minValue: function(this: any, value: string) {
+ if (this.CreateOilOrderForm.basicInfo.customer_asked_for_fill) return true;
+ if (!value) return true; // if empty, required will catch it
+ const num = parseInt(value, 10);
+ return num >= 1;
+ }
+ },
expected_delivery_date: { required },
+ credit_card_id: {
+ creditCardRequired: function(this: any, value: number) {
+ if (this.CreateOilOrderForm.basicInfo.credit) {
+ return value !== 0;
+ }
+ return true;
+ }
+ },
},
},
+ isAnyPaymentMethodSelected: {
+ mustBeTrue: (value: boolean) => value === true,
+ },
};
},
@@ -221,6 +338,25 @@ export default defineComponent({
}
return '';
},
+ isPricingTierSelected() {
+ return (tierGallons: number | string): boolean => {
+ if (!this.CreateOilOrderForm.basicInfo.gallons_ordered) return false;
+ const selectedGallons = Number(this.CreateOilOrderForm.basicInfo.gallons_ordered);
+ if (isNaN(selectedGallons)) return false;
+
+ const tierNum = Number(tierGallons);
+ if (isNaN(tierNum)) return false;
+
+ return selectedGallons === tierNum;
+ };
+ },
+ isAnyPaymentMethodSelected(): boolean {
+ return !!(this.CreateOilOrderForm.basicInfo?.credit || this.CreateOilOrderForm.basicInfo?.cash || this.CreateOilOrderForm.basicInfo?.check || this.CreateOilOrderForm.basicInfo?.other);
+ },
+ selectedGallonsAmount(): number {
+ const value = this.CreateOilOrderForm.basicInfo.gallons_ordered ?? '';
+ return Number(value);
+ }
},
mounted() {
@@ -233,6 +369,7 @@ export default defineComponent({
this.getPromos();
this.getDriversList();
this.getDeliveryStatusList();
+ this.getPricingTiers();
this.getDeliveryOrder(deliveryId);
},
@@ -244,6 +381,7 @@ export default defineComponent({
this.deliveryOrder = response.data.delivery; // <-- THIS IS THE CRITICAL CHANGE
// RESTORED: Populate all form fields from the API response
+ const paymentType = this.deliveryOrder.payment_type;
this.CreateOilOrderForm.basicInfo = {
gallons_ordered: String(this.deliveryOrder.gallons_ordered),
customer_asked_for_fill: !!this.deliveryOrder.customer_asked_for_fill,
@@ -256,8 +394,13 @@ export default defineComponent({
driver_employee_id: this.deliveryOrder.driver_employee_id || 0,
dispatcher_notes_taken: this.deliveryOrder.dispatcher_notes,
promo_id: this.deliveryOrder.promo_id || 0,
- payment_type: this.deliveryOrder.payment_type,
+ payment_type: paymentType,
credit_card_id: this.deliveryOrder.payment_card_id || 0,
+ // Set the correct payment method checkbox based on payment_type
+ credit: paymentType === 1,
+ cash: paymentType === 0,
+ check: paymentType === 3,
+ other: paymentType === 4,
};
this.getCustomer(this.deliveryOrder.customer_id);
@@ -304,23 +447,79 @@ export default defineComponent({
axios.get(`${import.meta.env.VITE_BASE_URL}/query/deliverystatus`, { withCredentials: true })
.then((response: any) => { this.deliveryStatus = response.data; });
},
+ getPricingTiers() {
+ let path = import.meta.env.VITE_BASE_URL + "/info/price/oil/tiers";
+ axios({ method: "get", url: path, withCredentials: true, headers: authHeader() })
+ .then((response: any) => {
+ const tiersObject = response.data;
+ this.pricingTiers = Object.entries(tiersObject).map(([gallons, price]) => ({
+ gallons: parseInt(gallons, 10),
+ price: price as string | number,
+ }));
+ })
+ .catch(() => {
+ notify({ title: "Pricing Error", text: "Could not retrieve today's pricing.", type: "error" });
+ });
+ },
+ editCard(card_id: number) {
+ this.$router.push({ name: "cardedit", params: { id: card_id } });
+ },
+ removeCard(card_id: number) {
+ if (window.confirm("Are you sure you want to remove this card?")) {
+ let path = `${import.meta.env.VITE_BASE_URL}/payment/card/remove/${card_id}`;
+ axios.delete(path, { headers: authHeader() })
+ .then(() => {
+ notify({ title: "Card Removed", type: "success" });
+ this.getPaymentCards(this.customer.id);
+ })
+ .catch(() => {
+ notify({ title: "Error", text: "Could not remove card.", type: "error" });
+ });
+ }
+ },
+ selectCreditCard(cardId: number) {
+ this.CreateOilOrderForm.basicInfo.credit_card_id = cardId;
+ },
+ setGallons(amount: number) {
+ this.CreateOilOrderForm.basicInfo.gallons_ordered = String(amount);
+ this.CreateOilOrderForm.basicInfo.customer_asked_for_fill = false;
+ },
+ setDeliveryDate(days: number) {
+ const date = new Date();
+ date.setDate(date.getDate() + days);
+ this.CreateOilOrderForm.basicInfo.expected_delivery_date = date.toISOString().split('T')[0];
+ },
+ isDeliveryDateSelected(days: number): boolean {
+ const date = new Date();
+ date.setDate(date.getDate() + days);
+ return this.CreateOilOrderForm.basicInfo.expected_delivery_date === date.toISOString().split('T')[0];
+ },
+ async onSubmit() {
+ const isFormValid = await this.v$.CreateOilOrderForm.$validate();
+ const isPaymentValid = await this.v$.isAnyPaymentMethodSelected.$validate();
- onSubmit() {
- this.v$.$validate();
- if (this.v$.$error) {
- notify({ type: 'error', title: 'Validation Error', text: 'Please check the form fields.' });
+ if (!isFormValid || !isPaymentValid) {
+ notify({ title: "Form Incomplete", text: "Please review the fields marked in red.", type: "warn" });
return;
}
const formInfo = this.CreateOilOrderForm.basicInfo;
+ // Convert checkboxes back to payment_type number for API
+ let paymentType = 0; // Default to cash
+ if (formInfo.credit) paymentType = 1;
+ else if (formInfo.cash) paymentType = 0;
+ else if (formInfo.other) paymentType = 4;
+ else if (formInfo.check) paymentType = 3;
+
// The payload now automatically includes all the restored fields
const payload = {
...formInfo,
- cash: formInfo.payment_type === 0,
- credit: formInfo.payment_type === 1,
- check: formInfo.payment_type === 3,
- other: formInfo.payment_type === 4,
- credit_card_id: formInfo.payment_type === 1 ? formInfo.credit_card_id : null,
+ payment_type: paymentType,
+ cash: formInfo.cash,
+ credit: formInfo.credit,
+ check: formInfo.check,
+ other: formInfo.other,
+ credit_card_id: formInfo.credit ? formInfo.credit_card_id : null,
};
axios.post(`${import.meta.env.VITE_BASE_URL}/delivery/edit/${this.deliveryOrder.id}`, payload, { withCredentials: true, headers: authHeader() })
diff --git a/src/pages/delivery/home.vue b/src/pages/delivery/home.vue
index e398ddd..094ef4f 100755
--- a/src/pages/delivery/home.vue
+++ b/src/pages/delivery/home.vue
@@ -20,13 +20,10 @@
-
Today's Deliveries
+
Deliveries
{{ delivery_count }}
-
-
Completed
-
{{ delivery_count_delivered }} / {{ delivery_count }}
-
+
diff --git a/src/pages/delivery/update_tickets/finalize_ticket.vue b/src/pages/delivery/update_tickets/finalize_ticket.vue
index ffd5174..d2e4a8b 100755
--- a/src/pages/delivery/update_tickets/finalize_ticket.vue
+++ b/src/pages/delivery/update_tickets/finalize_ticket.vue
@@ -538,26 +538,11 @@ async onSubmit() {
// If a valid, approved, pre-auth transaction is found...
if (transactionResponse.data && transactionResponse.data.transaction_type === 1 && transactionResponse.data.status === 0) {
-
+
// ...redirect to the capture page. The delivery is already updated.
- const gallons = this.FinalizeOilOrderForm.gallons_delivered || '0';
- const pricePerGallon = parseFloat(this.deliveryOrder.customer_price);
- let finalAmount = parseFloat(gallons) * pricePerGallon;
-
- if (this.deliveryOrder.prime == 1) {
- finalAmount += parseFloat(this.pricing.price_prime.toString()) || 0;
- }
- if (this.deliveryOrder.same_day == 1) {
- finalAmount += parseFloat(this.pricing.price_same_day.toString()) || 0;
- }
-
this.$router.push({
name: 'captureAuthorize',
- params: { id: this.$route.params.id },
- query: {
- gallons: gallons,
- amount: finalAmount.toFixed(2).toString()
- }
+ params: { id: this.$route.params.id }
});
} else {
diff --git a/src/pages/delivery/view.vue b/src/pages/delivery/view.vue
index 2900d71..c33b3f8 100755
--- a/src/pages/delivery/view.vue
+++ b/src/pages/delivery/view.vue
@@ -130,8 +130,8 @@