+ | {{ promo.id }} |
-
- {{ promo['name_of_promotion'] }}
+ {{ promo.name_of_promotion }}
|
- ${{ promo['money_off_delivery'] }}
+ ${{ promo.money_off_delivery }}
off/gal
|
- {{ promo['description'] }} |
- {{ promo['text_on_ticket'] }} |
+ {{ promo.description }} |
+ {{ promo.text_on_ticket }} |
-
Edit
-
@@ -91,32 +91,32 @@
-
+
- {{ promo['name_of_promotion'] }}
- ID: #{{ promo['id'] }}
+ {{ promo.name_of_promotion }}
+ ID: #{{ promo.id }}
- ${{ promo['money_off_delivery'] }} off/gal
+ ${{ promo.money_off_delivery }} off/gal
Description
- {{ promo['description'] }}
+ {{ promo.description }}
Ticket Text
{{
- promo['text_on_ticket'] }}
+ promo.text_on_ticket }}
- Edit
-
@@ -129,145 +129,67 @@
-
diff --git a/src/pages/auth/changepassword.vue b/src/pages/auth/changepassword.vue
index ee1269e..ea98b4f 100755
--- a/src/pages/auth/changepassword.vue
+++ b/src/pages/auth/changepassword.vue
@@ -3,7 +3,7 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/pages/auth/register.vue b/src/pages/auth/register.vue
index 9cfc6f2..f03b4bf 100755
--- a/src/pages/auth/register.vue
+++ b/src/pages/auth/register.vue
@@ -8,52 +8,54 @@
Register
-
-
- {{ v$.registerForm.username.$errors[0].$message }}
+
+
+ {{ v$.form.username.$errors[0].$message }}
-
-
-
- {{ v$.registerForm.email.$errors[0].$message }}
+
+
+
+ {{ v$.form.email.$errors[0].$message }}
-
-
- {{ v$.registerForm.password.$errors[0].$message }}
+
+
+ {{ v$.form.password.$errors[0].$message }}
-
-
- {{ v$.registerForm.password_confirm.$errors[0].$message }}
+
+
+ {{ v$.form.password_confirm.$errors[0].$message }}
Forgot Password?
+ class="text-center font-bold text-sm text-blue-500 hover:text-blue-800">Forgot Password?
Login Here
+ class="text-center font-bold text-sm text-blue-500 hover:text-blue-800">Login Here
@@ -61,104 +63,89 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/pages/automatic/home.vue b/src/pages/automatic/home.vue
index 4ccf570..10f8e46 100755
--- a/src/pages/automatic/home.vue
+++ b/src/pages/automatic/home.vue
@@ -26,12 +26,31 @@
Manage automatic delivery customers and schedules
+
+
+
- {{ deliveries.length }}
+ {{ sortedDeliveries.length }}
Customers
+
+ {{ urgentCount }}
+ Urgent (<=7 days)
+
@@ -41,57 +60,58 @@
-
-
+
+
-
-
-
-
-
+ |
+ Days Left
+ {{ sortAsc ? '▲' : '▼' }}
+ ⇵
+ |
+
-
- Hot Water Tank
- {{ sortAsc ? '▲' : '▼' }}
- ⇵
-
+ HW Tank
+ {{ sortAsc ? '▲' : '▼' }}
+ ⇵
|
- Address |
- Actions |
+ Address |
+ Actions |
-
|
@@ -108,32 +128,62 @@
| {{ oil.days_since_last_fill }} days |
- {{ oil.customer_full_name }}
+ class="group">
+
+ {{ oil.customer_full_name }}
+
+
+
+ #{{ oil.account_number }}
+
|
- {{ oil.house_factor }} |
- {{ oil.hot_water_summer ? 'Yes' : 'No' }} |
- {{ oil.customer_address }}, {{ oil.customer_town }} |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ |
+ {{ Number(oil.house_factor).toFixed(4) }}
+ |
+
+
+ {{ oil.confidence_score ?? 20 }}
+
+ |
+
+
+ N/A
+ {{ oil.days_remaining }}d
+ {{ oil.gallons_per_day }} gal/day
+
+ |
+ {{ oil.hot_water_summer ? 'Yes' : 'No' }} |
+
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
+ |
+
+
+ Auth
+ Final
+ Final
+ Print
+ Edit
+
|
@@ -141,14 +191,23 @@
-
+
{{ oil.customer_full_name }}
- {{ oil.customer_address }}, {{ oil.customer_town }}
+
+
+
+
+ {{ formatAddressStr(oil) }}
+
{{ oil.days_since_last_fill }}
@@ -160,12 +219,27 @@
Usage Factor
- {{ oil.house_factor }}
+ {{ Number(oil.house_factor).toFixed(4) }}
Hot Water Tank
{{ oil.hot_water_summer ? 'Yes' : 'No' }}
+
+ Confidence
+
+ {{ oil.confidence_score ?? 20 }}
+
+
+
+ Days Remaining
+ N/A
+ {{ oil.days_remaining }} days
+
Tank Level
@@ -185,18 +259,18 @@
Edit
+ class="btn btn-sm btn-info btn-outline flex-1">Edit
-
+
-
+
-
+
@@ -216,19 +290,38 @@ import { ref, computed, onMounted } from 'vue'
import axios from 'axios'
import authHeader from '../../services/auth.header'
import { AutoDelivery } from '../../types/models'
+import { formatAddress, getGoogleMapsLink } from '../../utils/addressUtils'
// Reactive data
const user = ref(null)
const deliveries = ref([])
// --- NEW: Data properties for sorting ---
-const sortKey = ref<'tank_level_percent' | 'hot_water_summer' | keyof AutoDelivery>('tank_level_percent')
+const sortKey = ref<'tank_level_percent' | 'hot_water_summer' | 'confidence_score' | 'days_remaining' | keyof AutoDelivery>('tank_level_percent')
const sortAsc = ref(true)
+const searchQuery = ref('')
-// Computed properties
-// --- NEW: Computed property to handle sorting ---
+// Computed: urgent count (<=7 days remaining)
+const urgentCount = computed((): number => {
+ return deliveries.value.filter(d => d.days_remaining != null && d.days_remaining <= 7 && d.days_remaining < 999).length
+})
+
+// Computed property to handle sorting AND searching
const sortedDeliveries = computed((): AutoDelivery[] => {
+ // First, filter by search query
+ let filtered = deliveries.value;
+
+ if (searchQuery.value && searchQuery.value.trim() !== '') {
+ const query = searchQuery.value.toLowerCase();
+ filtered = filtered.filter(item => {
+ const name = item.customer_full_name?.toLowerCase() || '';
+ const town = item.customer_town?.toLowerCase() || '';
+ const addr = item.customer_address?.toLowerCase() || '';
+ return name.includes(query) || town.includes(query) || addr.includes(query);
+ });
+ }
+
// Create a copy to avoid mutating the original array
- const sorted = [...deliveries.value];
+ const sorted = [...filtered];
sorted.sort((a, b) => {
// First, prioritize auto_status = 3 to be at the top
@@ -250,7 +343,6 @@ const sortedDeliveries = computed((): AutoDelivery[] => {
} else {
valA = a[sortKey.value as keyof AutoDelivery];
valB = b[sortKey.value as keyof AutoDelivery];
- // Special handling for hot_water_summer to ensure it's number
if (sortKey.value === 'hot_water_summer') {
valA = valA || 0;
valB = valB || 0;
@@ -258,8 +350,8 @@ const sortedDeliveries = computed((): AutoDelivery[] => {
}
// Handle nulls or different types if necessary
- if (valA === null) return 1;
- if (valB === null) return -1;
+ if (valA === null || valA === undefined) return 1;
+ if (valB === null || valB === undefined) return -1;
// Comparison logic
if (valA < valB) {
@@ -274,6 +366,22 @@ const sortedDeliveries = computed((): AutoDelivery[] => {
return sorted;
})
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus();
@@ -281,26 +389,37 @@ onMounted(() => {
})
// Functions
-// --- NEW: Method to handle sorting ---
-const sortBy = (key: keyof AutoDelivery | 'tank_level_percent' | 'hot_water_summer') => {
+const sortBy = (key: keyof AutoDelivery | 'tank_level_percent' | 'hot_water_summer' | 'confidence_score' | 'days_remaining') => {
if (sortKey.value === key) {
- // If clicking the same key, reverse the direction
sortAsc.value = !sortAsc.value;
} else {
- // If clicking a new key, set it and default to ascending
sortKey.value = key;
sortAsc.value = true;
}
}
-// --- NEW: Helper method for percentage calculation ---
const getTankLevelPercentage = (oil: AutoDelivery): number => {
if (!oil.tank_size || oil.tank_size === 0 || oil.last_fill === null) {
- return 0; // Return 0 if tank size is invalid or it's a new customer
+ return 0;
}
return (oil.estimated_gallons_left / oil.tank_size) * 100;
}
+const getConfidenceBadge = (score: number | null | undefined): string => {
+ const s = score ?? 20
+ if (s >= 70) return 'badge-success'
+ if (s >= 40) return 'badge-warning'
+ return 'badge-error'
+}
+
+const formatAddressStr = (oil: AutoDelivery): string => {
+ return formatAddress(oil.customer_address, oil.customer_town, oil.customer_state, oil.customer_zip);
+}
+
+const getMapLink = (oil: AutoDelivery): string => {
+ return getGoogleMapsLink(oil.customer_address, oil.customer_town, oil.customer_state, oil.customer_zip);
+}
+
const userStatus = () => {
const path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
axios.get(path, { withCredentials: true, headers: authHeader() })
diff --git a/src/pages/automatic/view.vue b/src/pages/automatic/view.vue
index de92bc8..13472e8 100644
--- a/src/pages/automatic/view.vue
+++ b/src/pages/automatic/view.vue
@@ -29,51 +29,58 @@
{{ autoTicket.customer_full_name }}
Account: {{ autoTicket.account_number }}
-
+
View Profile
- {{ autoTicket.customer_address }}
- Apt: {{ autoTicket.customer_apt }}
-
- {{ autoTicket.customer_town }},
- Massachusetts
- Rhode Island
- New Hampshire
- Maine
- Vermont
- Connecticut
- New York
- Unknown state
- {{ autoTicket.customer_zip }}
+
+
+
+
+
+ {{ autoTicket.customer_address }}
+ Apt: {{
+ autoTicket.customer_apt }}
+
+ {{ autoTicket.customer_town }},
+ {{ getStateName(autoTicket.customer_state) }}
+ {{ autoTicket.customer_zip }}
+
+
-
-
-
-
-
- Payment Status
-
- Unpaid
- Pre-authorized
- Processing
- Paid
- Failed
- Unknown
-
-
+
+
+
+
+ Payment Status
+
+ Unpaid
+ Pre-authorized
+ Processing
+ Paid
+ Failed
+ Unknown
+
+
Fill Date
{{ autoTicket.fill_date }}
@@ -103,7 +110,7 @@
-
+
@@ -141,7 +148,8 @@
Type:
- {{ transaction.transaction_type === 0 ? 'Charge' : transaction.transaction_type === 1 ? 'Auth' : transaction.transaction_type === 2 ? 'Capture' : 'Other' }}
+ {{ transaction.transaction_type === 0 ? 'Charge' : transaction.transaction_type === 1 ? 'Auth' :
+ transaction.transaction_type === 2 ? 'Capture' : 'Other' }}
@@ -200,8 +208,8 @@
+ class="p-4 rounded-lg border mt-2"
+ :class="userCard.main_card ? 'bg-primary/10 border-primary' : 'bg-base-200 border-base-300'">
{{ userCard.name_on_card }}
@@ -214,7 +222,8 @@
{{ userCard.card_number }}
Exp:
- 0{{ userCard.expiration_month }} / {{ userCard.expiration_year }}
+ 0{{ userCard.expiration_month }} / {{
+ userCard.expiration_year }}
CVV: {{ userCard.security_number }}
@@ -226,17 +235,18 @@
- Auto delivery processed automatically based on tank levels.
+ Auto delivery processed automatically based on tank levels.
+
-
+
-
+
-
diff --git a/src/pages/card/addcard.vue b/src/pages/card/addcard.vue
index 127c770..961a535 100755
--- a/src/pages/card/addcard.vue
+++ b/src/pages/card/addcard.vue
@@ -7,7 +7,8 @@
- Home
- Customers
- - Profile
+ - Profile
- Add Credit Card
@@ -30,7 +31,7 @@
Maine
New York
Unknown state
- {{ customer.customer_zip }}
+ {{ customer.customer_zip }}
{{ customer.customer_phone_number }}
@@ -52,74 +53,85 @@
Add a New Credit Card
-
+
-
diff --git a/src/pages/card/editcard.vue b/src/pages/card/editcard.vue
index c770dcf..874db6b 100755
--- a/src/pages/card/editcard.vue
+++ b/src/pages/card/editcard.vue
@@ -7,7 +7,8 @@
- Home
- Customers
- - Profile
+ - Profile
- Edit Credit Card
@@ -21,21 +22,23 @@
{{ customer.customer_first_name }} {{ customer.customer_last_name }}
Account: {{ customer.account_number }}
-
+
View Profile
{{ customer.customer_address }}
{{ customer.customer_apt }}
- {{ customer.customer_town }}, Massachusetts
+ {{ customer.customer_town }}, Massachusetts
Rhode Island
New Hampshire
Maine
Vermont
Connecticut
New York
- Unknown state {{ customer.customer_zip }}
+ Unknown state {{ customer.customer_zip }}
+
@@ -44,10 +47,10 @@
Editing Card
Card Type: {{ card.type_of_card }}
- Card Number: {{ card.card_number }}
-
+ Card Number: {{ card.card_number }}
+
- Loading card details...
+ Loading card details...
@@ -56,72 +59,82 @@
Update Card Details
-
+
-
diff --git a/src/pages/card/home.vue b/src/pages/card/home.vue
index 1a71e7f..a8b533c 100755
--- a/src/pages/card/home.vue
+++ b/src/pages/card/home.vue
@@ -1,201 +1,180 @@
-
-
+
+
- -
-
- Home
-
-
- -
-
- Customers
-
-
+ - Home
+ - Cards
-
-
-
-
+
+
+
+
+
+
+ Payment Cards
+
+ Manage customer payment cards
+
+
+
+
+
+ {{ cards.length }}
+ Total Cards
+
+
-
-
-
-
-
- | Name |
- Card Type |
- Card Number |
- Expiration |
- Main Card |
- |
-
-
-
-
-
- |
-
- {{ card['name_on_card'] }}
-
- |
- {{ card['type_of_card'] }} |
- {{ card['name_on_card'] }} |
- {{ card['expiration_month'] }} / {{ card['expiration_year'] }} |
- {{ card['main_card'] }} |
-
-
- Oil
-
-
- Service
-
+
+
+
+
+
+
+
+ | Card ID |
+ Customer |
+ Type |
+ Last 4 |
+ Expiration |
+ Main Card |
+ Actions |
+
+
+
+
+ | {{ card.id }} |
+ {{ card.customer_name || 'N/A' }} |
+ {{ card.type_of_card }} |
+ {{ card.card_number ? card.card_number.slice(-4) : 'XXXX' }} |
+ {{ card.expiration_month }}/{{ card.expiration_year }} |
+
+ Main
+ -
+ |
+
+
+ Edit
+
+
+ |
+
+
+
+
- x
- Remove Card
+
+
+
+
+
+
+ {{ card.type_of_card }}
+ ID: #{{ card.id }}
- |
-
-
-
+ Main
+
+
+
+ Last 4
+ {{ card.card_number ? card.card_number.slice(-4) : 'XXXX' }}
+
+
+ Expires
+ {{ card.expiration_month }}/{{ card.expiration_year }}
+
+
+
+ Edit
+
+
+
+
+
-
-
-
- {{ recordsLength }} items Found
-
-
-
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/pages/customer/home.vue b/src/pages/customer/home.vue
index 6794c47..80fa845 100755
--- a/src/pages/customer/home.vue
+++ b/src/pages/customer/home.vue
@@ -111,13 +111,13 @@
+ class="btn btn-xs btn-success btn-outline" title="New Delivery">
- Deliv
+ Delivery
- Svc
+ Service
View
+ class="btn btn-xs btn-neutral btn-outline">View
Edit
@@ -194,7 +194,7 @@
+ class="btn btn-sm btn-success btn-outline flex-1">
Delivery
+ class="btn btn-sm btn-neutral btn-outline flex-1">
View
diff --git a/src/pages/customer/profile/TankEstimation.vue b/src/pages/customer/profile/TankEstimation.vue
index 950e586..aa75ffa 100644
--- a/src/pages/customer/profile/TankEstimation.vue
+++ b/src/pages/customer/profile/TankEstimation.vue
@@ -1,6 +1,6 @@
-
+
+
+
+
+
+
+ {{ estimation.confidence_score }}%
+
+
+ Source: {{ estimation.k_factor_source }}
+
+
+
+
+
+
+
+ N/A
+ {{ estimation.days_remaining }} days
+
+
+
- {{ getScalingFactorCategory(estimation.scaling_factor) }}
- {{ formatScalingFactor(estimation.scaling_factor) }} gallons per degree day
+ {{ getScalingFactorCategory(sliderValue) }}
+ {{ sliderValue.toFixed(4) }} gal/degree day
- {{ calculateDailyUsage() }}
+ {{ computedGallonsPerDay }}
Gallons per day
+
+
+
+
+
+ 0.01
+
+ 1.00
+
+
+ {{ sliderValue.toFixed(4) }} gal/degree day
+ Saving...
+ Saved
+
+
@@ -78,7 +135,7 @@
+
+
diff --git a/src/pages/customer/profile/profile/AutomaticDeliveries.vue b/src/pages/customer/profile/profile/AutomaticDeliveries.vue
index bd53aa0..443982e 100644
--- a/src/pages/customer/profile/profile/AutomaticDeliveries.vue
+++ b/src/pages/customer/profile/profile/AutomaticDeliveries.vue
@@ -1,10 +1,7 @@
-
-
- Automatic Delivery History
-
-
+
diff --git a/src/pages/customer/profile/profile/ServiceCallsTable.vue b/src/pages/customer/profile/profile/ServiceCallsTable.vue
index 065af22..7f9de9a 100644
--- a/src/pages/customer/profile/profile/ServiceCallsTable.vue
+++ b/src/pages/customer/profile/profile/ServiceCallsTable.vue
@@ -2,9 +2,9 @@
- No service call history found for this customer.
+ No service calls found.
-
+
diff --git a/src/pages/customer/profile/profile/TankInfo.vue b/src/pages/customer/profile/profile/TankInfo.vue
index 87d7067..5067d66 100644
--- a/src/pages/customer/profile/profile/TankInfo.vue
+++ b/src/pages/customer/profile/profile/TankInfo.vue
@@ -1,9 +1,16 @@
-
+
- Tank Info
+
+
+ Tank Info
+
Edit
@@ -19,6 +26,30 @@
Location: {{ tank.outside_or_inside ? 'Inside' : 'Outside' }}
Size: {{ tank.tank_size }} Gallons
Fill Location: {{ description.fill_location }}
+
+
+
+
+
+ Confidence:
+
+ {{ estimation.confidence_score ?? 20 }}
+
+
+
+ K-Factor Source:
+ {{ estimation.k_factor_source || 'default' }}
+
+
+ Days Remaining:
+ N/A
+ {{ estimation.days_remaining }} days
+
+
@@ -28,6 +59,15 @@
defineProps({
customer_id: { type: Number, required: true },
tank: { type: Object, required: true },
- description: { type: Object, required: true }
+ description: { type: Object, required: true },
+ estimation: { type: Object, default: null }
});
-
\ No newline at end of file
+
+const getConfidenceBadge = (score: number | null | undefined): string => {
+ const s = score ?? 20
+ if (s >= 70) return 'badge-success'
+ if (s >= 40) return 'badge-warning'
+ return 'badge-error'
+}
+
+
diff --git a/src/pages/customer/profile/profile/TransactionsTable.vue b/src/pages/customer/profile/profile/TransactionsTable.vue
index 2d1445e..47fccb7 100644
--- a/src/pages/customer/profile/profile/TransactionsTable.vue
+++ b/src/pages/customer/profile/profile/TransactionsTable.vue
@@ -1,11 +1,11 @@
- No transaction history found.
+ No transactions found.
-
+
diff --git a/src/pages/delivery/create.vue b/src/pages/delivery/create.vue
index 4f5c27a..29699da 100755
--- a/src/pages/delivery/create.vue
+++ b/src/pages/delivery/create.vue
@@ -161,13 +161,46 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -344,7 +377,11 @@ interface DeliveryFormData {
credit_card_id?: number;
promo_id?: number;
driver_employee_id?: number;
- payment_type?: number; // Added for API payload construction
+ payment_type?: number;
+ // Tier fields
+ pricing_tier_same_day?: number;
+ pricing_tier_prime?: number;
+ pricing_tier_emergency?: number;
}
// Simplified Quick Add Card form data
interface CardFormData {
@@ -380,6 +417,9 @@ const formDelivery = ref({
prime: false,
emergency: false,
same_day: false,
+ pricing_tier_same_day: 0,
+ pricing_tier_prime: 0,
+ pricing_tier_emergency: 0,
credit: false,
cash: false,
check: false,
@@ -388,6 +428,13 @@ const formDelivery = ref({
promo_id: 0,
driver_employee_id: 0,
} as DeliveryFormData)
+
+// Tier pricing from API
+const tierPricing = ref({
+ same_day_tier1: 0, same_day_tier2: 0, same_day_tier3: 0, same_day_tier4: 0, same_day_tier5: 0,
+ prime_tier1: 0, prime_tier2: 0, prime_tier3: 0, prime_tier4: 0, prime_tier5: 0,
+ emergency_tier1: 0, emergency_tier2: 0, emergency_tier3: 0, emergency_tier4: 0, emergency_tier5: 0,
+})
// Simplified formCard data
const formCard = ref({
card_number: '',
@@ -509,6 +556,14 @@ const isPricingTierSelected = (tierGallons: number | string): boolean => {
return selectedGallons === tierNum;
}
+const formatCurrency = (value: number | string | undefined) => {
+ if (value === undefined || value === null) return '$0.00';
+ return new Intl.NumberFormat('en-US', {
+ style: 'currency',
+ currency: 'USD',
+ }).format(Number(value));
+}
+
const getPricingTiers = async () => {
try {
const response = await queryService.getOilPriceTiers();
@@ -601,6 +656,11 @@ const proceedWithSubmission = async () => {
else if(formDelivery.value.check) paymentType = 3;
else if(formDelivery.value.other) paymentType = 4;
+ // Update boolean flags based on tier selection for backward compatibility and logic
+ formDelivery.value.same_day = (formDelivery.value.pricing_tier_same_day || 0) > 0;
+ formDelivery.value.prime = (formDelivery.value.pricing_tier_prime || 0) > 0;
+ formDelivery.value.emergency = (formDelivery.value.pricing_tier_emergency || 0) > 0;
+
const payload = {
...formDelivery.value,
payment_type: paymentType,
@@ -744,6 +804,33 @@ onMounted(() => {
getDriversList()
getPromos()
getPricingTiers()
+
+ // Fetch full pricing table to populate tier dropdowns
+ queryService.getOilPriceTable().then((response: any) => {
+ const data = response.data.pricing;
+ if (data) {
+ tierPricing.value = {
+ same_day_tier1: data.price_same_day_tier1 || data.price_same_day,
+ same_day_tier2: data.price_same_day_tier2,
+ same_day_tier3: data.price_same_day_tier3,
+ same_day_tier4: data.price_same_day_tier4,
+ same_day_tier5: data.price_same_day_tier5,
+
+ prime_tier1: data.price_prime_tier1 || data.price_prime,
+ prime_tier2: data.price_prime_tier2,
+ prime_tier3: data.price_prime_tier3,
+ prime_tier4: data.price_prime_tier4,
+ prime_tier5: data.price_prime_tier5,
+
+ emergency_tier1: data.price_emergency_tier1 || data.price_emergency,
+ emergency_tier2: data.price_emergency_tier2,
+ emergency_tier3: data.price_emergency_tier3,
+ emergency_tier4: data.price_emergency_tier4,
+ emergency_tier5: data.price_emergency_tier5,
+ };
+ }
+ });
+
const customerId = route.params.id;
getCustomer(customerId)
getPaymentCards(customerId);
diff --git a/src/pages/delivery/edit.vue b/src/pages/delivery/edit.vue
index aa434ab..954670b 100755
--- a/src/pages/delivery/edit.vue
+++ b/src/pages/delivery/edit.vue
@@ -154,13 +154,46 @@
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -259,7 +292,11 @@ import adminService from '../../services/adminService';
import queryService from '../../services/queryService';
// Interfaces to describe the shape of your data
-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; }
+// Interfaces to describe the shape of your data
+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;
+ pricing_tier_same_day?: number; pricing_tier_prime?: number; pricing_tier_emergency?: number;
+}
interface PricingTier { gallons: number; price: string | number; }
const router = useRouter()
@@ -287,6 +324,9 @@ const CreateOilOrderForm = ref({
prime: false,
emergency: false,
same_day: false,
+ pricing_tier_same_day: 0,
+ pricing_tier_prime: 0,
+ pricing_tier_emergency: 0,
delivery_status: 0,
driver_employee_id: 0,
dispatcher_notes_taken: '',
@@ -300,6 +340,13 @@ const CreateOilOrderForm = ref({
},
})
+// Tier pricing from API
+const tierPricing = ref({
+ same_day_tier1: 0, same_day_tier2: 0, same_day_tier3: 0, same_day_tier4: 0, same_day_tier5: 0,
+ prime_tier1: 0, prime_tier2: 0, prime_tier3: 0, prime_tier4: 0, prime_tier5: 0,
+ emergency_tier1: 0, emergency_tier2: 0, emergency_tier3: 0, emergency_tier4: 0, emergency_tier5: 0,
+})
+
// Computed
const stateName = computed((): string => {
if (customer.value && customer.value.customer_state !== undefined) {
@@ -321,6 +368,14 @@ const isPricingTierSelected = computed(() => {
};
})
+const formatCurrency = (value: number | string | undefined) => {
+ if (value === undefined || value === null) return '$0.00';
+ return new Intl.NumberFormat('en-US', {
+ style: 'currency',
+ currency: 'USD',
+ }).format(Number(value));
+}
+
const isAnyPaymentMethodSelected = computed((): boolean => {
return !!(CreateOilOrderForm.value.basicInfo?.credit || CreateOilOrderForm.value.basicInfo?.cash || CreateOilOrderForm.value.basicInfo?.check || CreateOilOrderForm.value.basicInfo?.other);
})
@@ -384,9 +439,16 @@ const getDeliveryOrder = async (deliveryId: string) => {
customer_asked_for_fill: !!deliveryOrder.value.customer_asked_for_fill,
created_delivery_date: deliveryOrder.value.when_ordered,
expected_delivery_date: deliveryOrder.value.expected_delivery_date,
+ // Set tiers from delivery order
+ pricing_tier_same_day: deliveryOrder.value.pricing_tier_same_day || (deliveryOrder.value.same_day ? 1 : 0),
+ pricing_tier_prime: deliveryOrder.value.pricing_tier_prime || (deliveryOrder.value.prime ? 1 : 0),
+ pricing_tier_emergency: deliveryOrder.value.pricing_tier_emergency || (deliveryOrder.value.emergency ? 1 : 0),
+
+ // Set boolean flags for type compatibility and logic
+ same_day: !!deliveryOrder.value.same_day,
prime: !!deliveryOrder.value.prime,
emergency: !!deliveryOrder.value.emergency,
- same_day: !!deliveryOrder.value.same_day,
+
delivery_status: deliveryOrder.value.delivery_status,
driver_employee_id: deliveryOrder.value.driver_employee_id || 0,
dispatcher_notes_taken: deliveryOrder.value.dispatcher_notes,
@@ -475,6 +537,31 @@ const getPricingTiers = async () => {
gallons: parseInt(gallons, 10),
price: price as string | number,
}));
+
+ // Fetch full pricing table for dropdowns
+ const tableResponse = await queryService.getOilPriceTable();
+ const data = tableResponse.data.pricing;
+ if (data) {
+ tierPricing.value = {
+ same_day_tier1: data.price_same_day_tier1 || data.price_same_day,
+ same_day_tier2: data.price_same_day_tier2,
+ same_day_tier3: data.price_same_day_tier3,
+ same_day_tier4: data.price_same_day_tier4,
+ same_day_tier5: data.price_same_day_tier5,
+
+ prime_tier1: data.price_prime_tier1 || data.price_prime,
+ prime_tier2: data.price_prime_tier2,
+ prime_tier3: data.price_prime_tier3,
+ prime_tier4: data.price_prime_tier4,
+ prime_tier5: data.price_prime_tier5,
+
+ emergency_tier1: data.price_emergency_tier1 || data.price_emergency,
+ emergency_tier2: data.price_emergency_tier2,
+ emergency_tier3: data.price_emergency_tier3,
+ emergency_tier4: data.price_emergency_tier4,
+ emergency_tier5: data.price_emergency_tier5,
+ };
+ }
} catch (error) {
notify({ title: "Pricing Error", text: "Could not retrieve today's pricing.", type: "error" });
}
@@ -534,6 +621,11 @@ const onSubmit = async () => {
else if (formInfo.other) paymentType = 4;
else if (formInfo.check) paymentType = 3;
+ // Update boolean flags based on tier selection
+ formInfo.same_day = formInfo.pricing_tier_same_day > 0;
+ formInfo.prime = formInfo.pricing_tier_prime > 0;
+ formInfo.emergency = formInfo.pricing_tier_emergency > 0;
+
// The payload now automatically includes all the restored fields
const payload = {
...formInfo,
diff --git a/src/pages/delivery/home.vue b/src/pages/delivery/home.vue
index d57dea7..0af1828 100755
--- a/src/pages/delivery/home.vue
+++ b/src/pages/delivery/home.vue
@@ -90,9 +90,9 @@
FILL
- {{ oil.gallons_ordered }} gal
+ {{ oil.gallons_ordered }} gal
|
- {{ oil.expected_delivery_date }} |
+ {{ oil.expected_delivery_date }} |
PRIME
@@ -100,7 +100,7 @@
EMERGENCY
|
-
+ |
Cash
CC
Cash/CC
@@ -109,7 +109,7 @@
|
- View
+ View
Edit
Finalize
Print
@@ -169,7 +169,7 @@
Gallons
-
+
FILL
{{ oil.gallons_ordered }}
@@ -474,7 +474,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/delivery/map.vue b/src/pages/delivery/map.vue
index fa29bb5..ac382eb 100644
--- a/src/pages/delivery/map.vue
+++ b/src/pages/delivery/map.vue
@@ -33,9 +33,24 @@
{{ deliveries.length }} Deliveries
{{ uniqueTowns.length }} Towns
{{ mappedCount }} Mapped
+ {{ grandTotal.toLocaleString() }} Gallons
{{ unmappedCount }} Without Coordinates
+
+
+
+
+ {{ total.town }}
+ {{ total.gallons }} gal
+
+
+
+
@@ -200,6 +215,28 @@ const uniqueTowns = computed(() =>
[...new Set(deliveries.value.map(d => d.town))]
);
+interface TownTotal {
+ town: string;
+ gallons: number;
+}
+
+const townTotals = computed((): TownTotal[] => {
+ const totals: Record = {};
+ for (const delivery of deliveries.value) {
+ const town = delivery.town || 'Unknown';
+ // For fills, estimate 200 gallons; otherwise use ordered gallons
+ const gallons = delivery.isFill ? 200 : (delivery.gallonsOrdered || 0);
+ totals[town] = (totals[town] || 0) + gallons;
+ }
+ return Object.entries(totals)
+ .map(([town, gallons]) => ({ town, gallons }))
+ .sort((a, b) => b.gallons - a.gallons);
+});
+
+const grandTotal = computed(() => {
+ return townTotals.value.reduce((sum, t) => sum + t.gallons, 0);
+});
+
const groupedByTown = computed(() => {
const groups: Record = {};
for (const delivery of deliveries.value) {
diff --git a/src/pages/delivery/update_tickets/finalize_ticket.vue b/src/pages/delivery/update_tickets/finalize_ticket.vue
index 9bb844d..d2147f7 100755
--- a/src/pages/delivery/update_tickets/finalize_ticket.vue
+++ b/src/pages/delivery/update_tickets/finalize_ticket.vue
@@ -87,8 +87,18 @@
- Prime Fee ${{ Number(pricing.price_prime).toFixed(2) }}
- Same Day Fee ${{ Number(pricing.price_same_day).toFixed(2) }}
+
+ Prime Fee (Tier {{ deliveryOrder.pricing_tier_prime || 1 }})
+ ${{ Number(getTierPrice('prime', deliveryOrder.pricing_tier_prime)).toFixed(2) }}
+
+
+ Same Day Fee (Tier {{ deliveryOrder.pricing_tier_same_day || 1 }})
+ ${{ Number(getTierPrice('same_day', deliveryOrder.pricing_tier_same_day)).toFixed(2) }}
+
+
+ Emergency Fee (Tier {{ deliveryOrder.pricing_tier_emergency || 1 }})
+ ${{ Number(getTierPrice('emergency', deliveryOrder.pricing_tier_emergency)).toFixed(2) }}
+
@@ -319,14 +329,15 @@ const deliveryOrder = ref({
customer_price: '',
prime: 0,
same_day: 0,
+ emergency: 0,
+ pricing_tier_same_day: 0,
+ pricing_tier_prime: 0,
+ pricing_tier_emergency: 0,
payment_type: 0,
payment_card_id: '',
promo_id: null,
})
-const pricing = ref({
- price_prime: 0,
- price_same_day: 0,
-})
+const pricing = ref({} as any)
const promo_active = ref(false)
const promo = ref({
name_of_promotion: '',
@@ -356,11 +367,28 @@ const finalChargeAmount = computed((): number => {
return 0;
}
let total = gallons * pricePerGallon;
- if (deliveryOrder.value.prime === 1) total += Number(pricing.value.price_prime);
- if (deliveryOrder.value.same_day === 1) total += Number(pricing.value.price_same_day);
+
+ if (deliveryOrder.value.prime === 1) {
+ total += Number(getTierPrice('prime', deliveryOrder.value.pricing_tier_prime));
+ }
+ if (deliveryOrder.value.same_day === 1) {
+ total += Number(getTierPrice('same_day', deliveryOrder.value.pricing_tier_same_day));
+ }
+ if (deliveryOrder.value.emergency === 1) {
+ total += Number(getTierPrice('emergency', deliveryOrder.value.pricing_tier_emergency));
+ }
+
return total;
})
+const getTierPrice = (serviceType: string, tier: number | undefined) => {
+ const tierNum = tier || 1;
+ const key = `price_${serviceType}_tier${tierNum}`;
+ // Fallback to legacy single price if tier specific not found, though API should provide all
+ const price = pricing.value[key] !== undefined ? pricing.value[key] : pricing.value[`price_${serviceType}`];
+ return Number(price || 0);
+}
+
// Lifecycle
onMounted(() => {
const deliveryId = route.params.id;
diff --git a/src/pages/delivery/viewstatus/cancelled.vue b/src/pages/delivery/viewstatus/cancelled.vue
index 955e9b2..e77a11c 100755
--- a/src/pages/delivery/viewstatus/cancelled.vue
+++ b/src/pages/delivery/viewstatus/cancelled.vue
@@ -37,15 +37,25 @@
+
+
+
+ No deliveries found
+ No cancelled deliveries
+
+
-
+
- | Delivery # |
- Name |
+ Customer |
Status |
- Town / Address |
+ Address |
Gallons |
Date |
Options |
@@ -54,26 +64,49 @@
-
- | {{ oil.id }} |
+
|
-
- {{ oil.customer_name }}
+
+
+ {{ oil.customer_name }}
+
+
- {{ oil.customer_name }}
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
|
Cancelled
|
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
|
FILL
- {{ oil.gallons_ordered }} gal
+ {{ oil.gallons_ordered }} gal
|
- {{ oil.expected_delivery_date }} |
+ {{ oil.expected_delivery_date }} |
PRIME
@@ -82,7 +115,7 @@
|
- View
+ View
Edit
|
@@ -128,7 +161,7 @@
Gallons
-
+
FILL
{{ oil.gallons_ordered }}
@@ -236,6 +269,22 @@ const deleteCall = async (delivery_id: number) => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
@@ -393,7 +442,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/delivery/viewstatus/delivered.vue b/src/pages/delivery/viewstatus/delivered.vue
index 1d11ae8..3cd1ef5 100755
--- a/src/pages/delivery/viewstatus/delivered.vue
+++ b/src/pages/delivery/viewstatus/delivered.vue
@@ -37,15 +37,25 @@
+
+
+
+ No deliveries found
+ No delivered deliveries awaiting finalization
+
+
-
+
- | Delivery # |
- Name |
+ Customer |
Status |
- Town / Address |
+ Address |
Gallons |
Date |
Options |
@@ -54,26 +64,49 @@
-
- | {{ oil.id }} |
+
|
-
- {{ oil.customer_name }}
+
+
+ {{ oil.customer_name }}
+
+
- {{ oil.customer_name }}
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
|
Delivered
|
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
|
FILL
- {{ oil.gallons_ordered }} gal
+ {{ oil.gallons_ordered }} gal
|
- {{ oil.expected_delivery_date }} |
+ {{ oil.expected_delivery_date }} |
PRIME
@@ -129,7 +162,7 @@
Gallons
-
+
FILL
{{ oil.gallons_ordered }}
@@ -237,6 +270,22 @@ const deleteCall = async (delivery_id: number) => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
@@ -394,7 +443,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/delivery/viewstatus/finalized.vue b/src/pages/delivery/viewstatus/finalized.vue
index f6a5fc1..3366c1b 100644
--- a/src/pages/delivery/viewstatus/finalized.vue
+++ b/src/pages/delivery/viewstatus/finalized.vue
@@ -33,18 +33,29 @@
+
+
+
+
+ No deliveries found
+ No finalized deliveries
+
+
-
+
- | Ticket # |
- Name |
+ Customer |
Status |
- Town / Address |
+ Address |
Gallons Delivered |
Date |
Options |
@@ -53,26 +64,49 @@
-
- | {{ oil.id }} |
+
|
-
- {{ oil.customer_name }}
+
+
+ {{ oil.customer_name }}
+
+
- {{ oil.customer_name }}
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
|
Finalized
|
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
|
- {{ oil.gallons_delivered }} gal
+ {{ oil.gallons_delivered }} gal
|
- {{ oil.expected_delivery_date }} |
+ {{ oil.expected_delivery_date }} |
PRIME
@@ -81,7 +115,7 @@
|
- View
+ View
Edit
Print
@@ -128,7 +162,7 @@
Gallons
-
+
{{ oil.gallons_delivered }} gal
@@ -235,6 +269,22 @@ const deleteCall = async (delivery_id: number) => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
@@ -392,7 +442,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/delivery/viewstatus/issue.vue b/src/pages/delivery/viewstatus/issue.vue
index cfb4161..b82f26a 100755
--- a/src/pages/delivery/viewstatus/issue.vue
+++ b/src/pages/delivery/viewstatus/issue.vue
@@ -33,18 +33,29 @@
+
+
+
+
+ No deliveries found
+ No deliveries with issues
+
+
-
+
- | Ticket # |
- Name |
+ Customer |
Status |
- Town / Address |
+ Address |
Gallons |
Date |
Options |
@@ -53,26 +64,49 @@
-
- | {{ oil.id }} |
+
|
-
- {{ oil.customer_name }}
+
+
+ {{ oil.customer_name }}
+
+
- {{ oil.customer_name }}
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
|
Issue
|
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
|
FILL
- {{ oil.gallons_ordered }} gal
+ {{ oil.gallons_ordered }} gal
|
- {{ oil.expected_delivery_date }} |
+ {{ oil.expected_delivery_date }} |
PRIME
@@ -81,7 +115,7 @@
|
- View
+ View
Edit
Print
@@ -128,7 +162,7 @@
Gallons
-
+
FILL
{{ oil.gallons_ordered }}
@@ -236,6 +270,22 @@ const deleteCall = async (delivery_id: number) => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
@@ -393,7 +443,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/delivery/viewstatus/pending.vue b/src/pages/delivery/viewstatus/pending.vue
index db9dc72..b8bd9f5 100644
--- a/src/pages/delivery/viewstatus/pending.vue
+++ b/src/pages/delivery/viewstatus/pending.vue
@@ -35,15 +35,25 @@
+
+
+
+ No deliveries found
+ No pending deliveries awaiting payment or credit approval
+
+
-
+
- | Delivery # |
- Name |
+ Customer |
Status |
- Town / Address |
+ Address |
Gallons |
Payment |
Options |
@@ -52,13 +62,23 @@
-
- | {{ oil.id }} |
+
|
-
- {{ oil.customer_name }}
+
+
+ {{ oil.customer_name }}
+
+
- {{ oil.customer_name }}
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
|
Waiting
Cancelled
- Out_for_Delivery
+ Out for Delivery
Finalized
N/A
|
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
|
FILL
- {{ oil.gallons_ordered }} gal
+ {{ oil.gallons_ordered }} gal
|
-
+ |
Cash
CC
Cash/CC
@@ -98,7 +131,7 @@
|
- View
+ View
Edit
Finalize
Print
@@ -111,7 +144,7 @@
-
+
Gallons
-
+
FILL
{{ oil.gallons_ordered }}
@@ -274,6 +307,22 @@ const deleteCall = async (delivery_id: number) => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
@@ -431,7 +480,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/delivery/viewstatus/todaysdeliveries.vue b/src/pages/delivery/viewstatus/todaysdeliveries.vue
index b424214..9d1aabd 100755
--- a/src/pages/delivery/viewstatus/todaysdeliveries.vue
+++ b/src/pages/delivery/viewstatus/todaysdeliveries.vue
@@ -84,7 +84,7 @@
/>
-
+
@@ -126,7 +126,8 @@
Customer |
Status |
- Location |
+ Address |
+
| |
-
-
-
- {{ oil.customer_name }}
-
- {{ oil.customer_name }}
-
-
-
-
- EMERGENCY
-
-
-
- PRIME
-
-
-
- SAME DAY
-
-
+
+
+ {{ oil.customer_name }}
+
+
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
+
+
+
+
+ EMERGENCY
+
+
+
+ PRIME
+
+
+
+ SAME DAY
+
|
@@ -190,14 +198,19 @@
|
-
-
-
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
|
@@ -208,14 +221,13 @@
FILL
-
- {{ oil.gallons_ordered }}
- gal
+
+ {{ oil.gallons_ordered }} gal
-
+
View
@@ -289,7 +301,7 @@
Gallons
-
+
FILL
{{ oil.gallons_ordered }} gal
@@ -298,7 +310,7 @@
-
+
View
@@ -492,6 +504,22 @@ const get_totals = async () => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
@@ -650,7 +678,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/delivery/viewstatus/tommorrow.vue b/src/pages/delivery/viewstatus/tommorrow.vue
index d26a9c5..6130233 100644
--- a/src/pages/delivery/viewstatus/tommorrow.vue
+++ b/src/pages/delivery/viewstatus/tommorrow.vue
@@ -87,31 +87,53 @@
-
+
+
+
+ No deliveries found
+ {{ searchQuery || filterTown ? 'Try adjusting your search or filter' : 'No deliveries scheduled for tomorrow' }}
+
-
+
- | Delivery # |
- Name |
+ Customer |
Status |
- Town / Address |
+ Address |
Gallons |
-
Actions |
-
- | {{ oil.id }} |
+
|
-
- {{ oil.customer_name }}
+
+
+ {{ oil.customer_name }}
+
+
- {{ oil.customer_name }}
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
+
+
+ PRIME
+ SAME DAY
+
|
Waiting
Cancelled
- Out_for_Delivery
+ Out for Delivery
Tomorrow
Partial
Issue
@@ -130,22 +152,29 @@
|
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
|
FILL
- {{ oil.gallons_ordered }} gal
- |
-
-
- PRIME
- SAME DAY
-
+ {{ oil.gallons_ordered }} gal
|
- View
+ View
Edit
Finalize
Print
@@ -206,7 +235,7 @@
Gallons
-
+
FILL
{{ oil.gallons_ordered }}
@@ -430,6 +459,22 @@ const printTicket = async (delivery_id: number) => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
diff --git a/src/pages/delivery/viewstatus/waiting.vue b/src/pages/delivery/viewstatus/waiting.vue
index db9bb3a..aa7b13d 100755
--- a/src/pages/delivery/viewstatus/waiting.vue
+++ b/src/pages/delivery/viewstatus/waiting.vue
@@ -87,17 +87,25 @@
-
+
+
+
+ No deliveries found
+ {{ searchQuery || filterTown ? 'Try adjusting your search or filter' : 'No deliveries are waiting for dispatch' }}
+
-
+
- | Delivery # |
- Name |
+ Customer |
Status |
- Town / Address |
+ Address |
Gallons |
Date |
Options |
@@ -106,13 +114,23 @@
-
- | {{ oil.id }} |
+
|
-
- {{ oil.customer_name }}
+
+
+ {{ oil.customer_name }}
+
+
- {{ oil.customer_name }}
+
+ {{ oil.customer_name }}
+ #{{ oil.id }}
+
|
@@ -120,14 +138,27 @@
|
- {{ oil.customer_town }}
- {{ oil.customer_address }}
+
+ {{ oil.customer_address }}
+
+ {{ oil.customer_town }}, {{ getStateAbbr(oil.customer_state) }} {{ oil.customer_zip }}
+
+
+
+
+
|
FILL
- {{ oil.gallons_ordered }} gal
+ {{ oil.gallons_ordered }} gal
|
- {{ oil.expected_delivery_date }} |
+ {{ oil.expected_delivery_date }} |
PRIME
@@ -136,7 +167,7 @@
|
- View
+ View
Edit
Finalize
Print
@@ -184,7 +215,7 @@
Gallons
-
+
FILL
{{ oil.gallons_ordered }}
@@ -345,6 +376,22 @@ const deleteCall = async (delivery_id: number) => {
}
}
+// State abbreviation mapping
+const STATE_ABBR_MAP: { [key: number]: string } = {
+ 0: 'MA', 1: 'RI', 2: 'NH', 3: 'ME', 4: 'VT', 5: 'CT', 6: 'NY', 7: 'NJ',
+ 8: 'PA', 9: 'DE', 10: 'MD', 11: 'DC', 12: 'VA', 13: 'WV', 14: 'NC',
+ 15: 'SC', 16: 'GA', 17: 'FL', 18: 'AL', 19: 'MS', 20: 'TN', 21: 'KY',
+ 22: 'OH', 23: 'IN', 24: 'MI', 25: 'IL', 26: 'WI', 27: 'MN', 28: 'IA',
+ 29: 'MO', 30: 'AR', 31: 'LA', 32: 'TX', 33: 'OK', 34: 'KS', 35: 'NE',
+ 36: 'SD', 37: 'ND', 38: 'MT', 39: 'WY', 40: 'CO', 41: 'NM', 42: 'AZ',
+ 43: 'UT', 44: 'NV', 45: 'ID', 46: 'WA', 47: 'OR', 48: 'CA', 49: 'AK', 50: 'HI'
+}
+
+const getStateAbbr = (stateId: number | string): string => {
+ const id = typeof stateId === 'string' ? parseInt(stateId) : stateId;
+ return STATE_ABBR_MAP[id] || 'MA';
+}
+
// Lifecycle
onMounted(() => {
userStatus()
@@ -503,7 +550,7 @@ onMounted(() => {
/* Gallons Badge */
.gallons-badge {
- @apply inline-flex items-center gap-1 px-3 py-1.5 rounded-lg bg-success/10 border border-success/20 text-success font-mono text-lg font-bold shadow-sm;
+ @apply text-success font-mono font-bold;
}
.gallons-fill {
@apply bg-info/10 text-info border-info/20;
diff --git a/src/pages/employee/changepassword.vue b/src/pages/employee/changepassword.vue
index d563ea6..43dbe42 100644
--- a/src/pages/employee/changepassword.vue
+++ b/src/pages/employee/changepassword.vue
@@ -27,24 +27,25 @@
-
-
- {{ v$.ChangePasswordForm.new_password.$errors[0].$message }}
+
+
+ {{ v$.form.new_password.$errors[0].$message }}
-
-
- {{ v$.ChangePasswordForm.password_confirm.$errors[0].$message }}
+
+
+ {{ v$.form.password_confirm.$errors[0].$message }}
@@ -54,142 +55,124 @@
-
diff --git a/src/pages/employee/create.vue b/src/pages/employee/create.vue
index 5d46a48..68d192d 100755
--- a/src/pages/employee/create.vue
+++ b/src/pages/employee/create.vue
@@ -27,37 +27,44 @@
-
-
- {{ v$.CreateEmployeeForm.employee_first_name.$errors[0].$message }}
+
+
+ {{ v$.form.employee_first_name.$errors[0].$message }}
-
-
- {{ v$.CreateEmployeeForm.employee_last_name.$errors[0].$message }}
+
+
+ {{ v$.form.employee_last_name.$errors[0].$message }}
-
-
- {{ v$.CreateEmployeeForm.employee_phone_number.$errors[0].$message }}
+
+
+ {{ v$.form.employee_phone_number.$errors[0].$message }}
-
@@ -72,44 +79,51 @@
-
-
- {{ v$.CreateEmployeeForm.employee_address.$errors[0].$message }}
+
+
+ {{ v$.form.employee_address.$errors[0].$message }}
-
- Required.
+
-
-
- {{ v$.CreateEmployeeForm.employee_town.$errors[0].$message }}
+
+
+ {{ v$.form.employee_town.$errors[0].$message }}
-
+
-
+
State is required.
-
-
- {{ v$.CreateEmployeeForm.employee_zip.$errors[0].$message }}
+
+
+ {{ v$.form.employee_zip.$errors[0].$message }}
@@ -122,144 +136,153 @@
-
+
-
+
-
\ No newline at end of file
diff --git a/src/pages/employee/edit.vue b/src/pages/employee/edit.vue
index ef66390..547b3de 100755
--- a/src/pages/employee/edit.vue
+++ b/src/pages/employee/edit.vue
@@ -15,7 +15,8 @@
Edit Employee
-
+
Back to Profile
@@ -32,37 +33,44 @@
-
-
- {{ v$.CreateEmployeeForm.employee_first_name.$errors[0].$message }}
+
+
+ {{ v$.form.employee_first_name.$errors[0].$message }}
-
-
- {{ v$.CreateEmployeeForm.employee_last_name.$errors[0].$message }}
+
+
+ {{ v$.form.employee_last_name.$errors[0].$message }}
-
-
- {{ v$.CreateEmployeeForm.employee_phone_number.$errors[0].$message }}
+
+
+ {{ v$.form.employee_phone_number.$errors[0].$message }}
-
+
-
+
Role is required.
@@ -77,43 +85,51 @@
-
-
- {{ v$.CreateEmployeeForm.employee_address.$errors[0].$message }}
+
+
+ {{ v$.form.employee_address.$errors[0].$message }}
-
+
-
-
- {{ v$.CreateEmployeeForm.employee_town.$errors[0].$message }}
+
+
+ {{ v$.form.employee_town.$errors[0].$message }}
-
+
-
+
State is required.
-
-
- {{ v$.CreateEmployeeForm.employee_zip.$errors[0].$message }}
+
+
+ {{ v$.form.employee_zip.$errors[0].$message }}
@@ -126,180 +142,192 @@
-
+
-
+
-
+
-
diff --git a/src/pages/employee/home.vue b/src/pages/employee/home.vue
index 8aed33f..197bb04 100755
--- a/src/pages/employee/home.vue
+++ b/src/pages/employee/home.vue
@@ -1,6 +1,6 @@
-
+
@@ -13,9 +13,12 @@
-
- | | | | | | | | |