Bulk Dell warranty sync + add-warranty from asset pages
- POST /warranty/sync/dell: auto-detect Dell hardware by service tag (asset serial) and create warranties for the ones Dell recognizes, in batches of 100. Only looks up assets that lack a dated warranty, so re-runs are cheap and non-Dell serials are filtered out by Dell. DellProvider.bulk_lookup batches tags over the cached token. - "Sync Dell" button on the Warranties page with a toast summary. - WarrantyPanel "Add one / Add-manage" links deep-link to the warranties add modal pre-linked to that asset (?addfor=); WarrantiesList opens it prefilled. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -970,6 +970,9 @@ export const warrantyApi = {
|
||||
refresh(id) {
|
||||
return api.post(`/warranty/${id}/refresh`)
|
||||
},
|
||||
syncDell() {
|
||||
return api.post('/warranty/sync/dell')
|
||||
},
|
||||
report() {
|
||||
return api.get('/warranty/report')
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
<span v-if="w.servicetag" class="mono">Tag {{ w.servicetag }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<router-link to="/warranties" class="warranty-manage">Manage warranties</router-link>
|
||||
<router-link :to="`/warranties?addfor=${assetid}`" class="warranty-manage">Add / manage</router-link>
|
||||
</div>
|
||||
|
||||
<div v-else class="warranty-empty">
|
||||
<span class="muted">No warranty on record.</span>
|
||||
<router-link to="/warranties" class="warranty-manage">Add one</router-link>
|
||||
<router-link :to="`/warranties?addfor=${assetid}`" class="warranty-manage">Add one</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
<div>
|
||||
<div class="page-header">
|
||||
<h2>Warranties</h2>
|
||||
<button class="btn btn-primary" @click="openModal()">+ Add Warranty</button>
|
||||
<div class="header-actions">
|
||||
<button class="btn btn-secondary" :disabled="syncing" @click="syncDell">
|
||||
{{ syncing ? 'Syncing Dell...' : 'Sync Dell' }}
|
||||
</button>
|
||||
<button class="btn btn-primary" @click="openModal()">+ Add Warranty</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -137,14 +142,17 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { colorStyle } from '@/utils/colorStyle'
|
||||
import { warrantyApi, assetsApi } from '../../api'
|
||||
import { useToast } from '../../composables/toast'
|
||||
|
||||
const toast = useToast()
|
||||
const route = useRoute()
|
||||
|
||||
const items = ref([])
|
||||
const loading = ref(true)
|
||||
const syncing = ref(false)
|
||||
const statusFilter = ref('')
|
||||
const showModal = ref(false)
|
||||
const editing = ref(null)
|
||||
@@ -171,7 +179,21 @@ function assetLink(a) {
|
||||
return base + a.assetid
|
||||
}
|
||||
|
||||
onMounted(loadData)
|
||||
onMounted(async () => {
|
||||
await loadData()
|
||||
// Deep-link from an asset detail page: open the add modal pre-linked to it.
|
||||
const addfor = route.query.addfor
|
||||
if (addfor) {
|
||||
openModal()
|
||||
try {
|
||||
const response = await assetsApi.get(addfor)
|
||||
const asset = response.data.data
|
||||
if (asset) selectedAssets.value = [{ assetid: asset.assetid, assetnumber: asset.assetnumber }]
|
||||
} catch (err) {
|
||||
selectedAssets.value = [{ assetid: Number(addfor), assetnumber: `Asset ${addfor}` }]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
async function loadData() {
|
||||
loading.value = true
|
||||
@@ -269,6 +291,21 @@ async function deleteWarranty(w) {
|
||||
}
|
||||
}
|
||||
|
||||
async function syncDell() {
|
||||
syncing.value = true
|
||||
toast.info('Looking up Dell service tags... this can take a moment.')
|
||||
try {
|
||||
const response = await warrantyApi.syncDell()
|
||||
const summary = response.data?.data || {}
|
||||
loadData()
|
||||
toast.success(`Dell sync: ${summary.created || 0} added, ${summary.updated || 0} updated (${summary.matched || 0} tags matched).`)
|
||||
} catch (err) {
|
||||
toast.error(apiError(err, 'Dell sync failed'))
|
||||
} finally {
|
||||
syncing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function refresh(w) {
|
||||
try {
|
||||
const response = await warrantyApi.refresh(w.warrantyid)
|
||||
|
||||
Reference in New Issue
Block a user