update importWorkflow plugin/fix storeroom pdf print

This commit is contained in:
Gloomy 2025-08-30 13:35:38 +00:00
parent 0fb64e8cfa
commit 3d490ffe51
5 changed files with 202 additions and 131 deletions

View file

@ -1,4 +1,14 @@
<template>
<v-toolbar color="toolbar" :title="'لیست پرونده‌های واردات'">
<template v-slot:prepend>
<v-tooltip :text="$t('dialog.back')" location="bottom">
<template v-slot:activator="{ props }">
<v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text"
icon="mdi-arrow-right" />
</template>
</v-tooltip>
</template>
</v-toolbar>
<div class="import-workflow-list">
<v-container fluid>
<!-- Stats Cards -->
@ -93,72 +103,33 @@
<v-row>
<v-col cols="12">
<v-card>
<v-data-table
:headers="headers"
:items="workflows"
:loading="loading"
density="comfortable"
class="elevation-1"
:header-props="{ class: 'custom-header' }"
hover
>
<v-data-table :headers="headers" :items="workflows" :loading="loading" density="comfortable"
class="elevation-1" :header-props="{ class: 'custom-header' }" hover>
<template v-slot:top>
<!-- موبایل -->
<div class="d-block d-md-none pa-4">
<div class="d-flex gap-2 flex-column mb-3">
<v-btn
color="primary"
prepend-icon="mdi-plus"
@click="showCreateDialog = true"
size="small"
block
>
<v-btn color="primary" prepend-icon="mdi-plus" @click="showCreateDialog = true" size="small" block>
پرونده واردات جدید
</v-btn>
</div>
<v-text-field
v-model="filters.search"
label="جستجو"
prepend-icon="mdi-magnify"
clearable
density="compact"
variant="outlined"
hide-details
class="mb-3"
@update:model-value="loadWorkflows"
/>
<v-text-field v-model="filters.search" label="جستجو" prepend-icon="mdi-magnify" clearable
density="compact" variant="outlined" hide-details class="mb-3"
@update:model-value="loadWorkflows" />
</div>
<!-- دسکتاپ -->
<div class="d-none d-md-block">
<v-toolbar flat style="height: 70px !important; padding: 10px !important;">
<v-text-field
v-model="filters.search"
label="جستجو"
prepend-icon="mdi-magnify"
clearable
density="compact"
variant="outlined"
hide-details
style="max-width: 250px;"
@update:model-value="loadWorkflows"
class="ml-2"
/>
<v-text-field v-model="filters.search" label="جستجو" prepend-icon="mdi-magnify" clearable
density="compact" variant="outlined" hide-details style="max-width: 250px;"
@update:model-value="loadWorkflows" class="ml-2" />
<v-spacer></v-spacer>
<v-btn
color="info"
prepend-icon="mdi-chart-line"
@click="goToReports"
variant="outlined"
class="ml-2"
>
<v-btn color="info" prepend-icon="mdi-chart-line" @click="goToReports" variant="outlined"
class="ml-2">
گزارشات
</v-btn>
<v-btn
color="primary"
prepend-icon="mdi-plus"
@click="showCreateDialog = true"
>
<v-btn color="primary" prepend-icon="mdi-plus" @click="showCreateDialog = true">
پرونده واردات جدید
</v-btn>
</v-toolbar>
@ -179,13 +150,7 @@
<template v-slot:item.actions="{ item }">
<v-menu>
<template v-slot:activator="{ props }">
<v-btn
v-bind="props"
icon="mdi-menu"
variant="text"
size="small"
color="error"
></v-btn>
<v-btn v-bind="props" icon="mdi-menu" variant="text" size="small" color="error"></v-btn>
</template>
<v-list>
<v-list-item @click="viewWorkflow(item)">
@ -216,10 +181,7 @@
</v-container>
<!-- Create Dialog -->
<ImportWorkflowCreateDialog
v-model="showCreateDialog"
@created="onWorkflowCreated"
/>
<ImportWorkflowCreateDialog v-model="showCreateDialog" @created="onWorkflowCreated" />
<!-- Delete Confirmation Dialog -->
<v-dialog v-model="showDeleteDialog" max-width="400">
@ -237,14 +199,8 @@
</v-dialog>
<!-- Snackbar for notifications -->
<v-snackbar
v-model="showSnackbar"
:color="snackbarColor"
:timeout="3000"
location="bottom"
class="rounded-lg"
elevation="2"
>
<v-snackbar v-model="showSnackbar" :color="snackbarColor" :timeout="3000" location="bottom" class="rounded-lg"
elevation="2">
<div class="d-flex align-center">
<v-icon :color="snackbarColor" class="me-2">
{{ snackbarColor === 'success' ? 'mdi-check-circle' : 'mdi-alert-circle' }}
@ -505,7 +461,7 @@ onMounted(async () => {
}
.stats-card.active-filter::before {
background: linear-gradient(45deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.1) 100%);
background: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%);
}
.stats-card::before {
@ -515,7 +471,7 @@ onMounted(async () => {
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%);
background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
border-radius: 16px;
z-index: 1;
}
@ -580,5 +536,3 @@ onMounted(async () => {
}
}
</style>

View file

@ -1,28 +1,17 @@
<template>
<v-toolbar color="toolbar" :title="'داشبورد گزارشات واردات'">
<template v-slot:prepend>
<v-tooltip :text="$t('dialog.back')" location="bottom">
<template v-slot:activator="{ props }">
<v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text"
icon="mdi-arrow-right" />
</template>
</v-tooltip>
</template>
</v-toolbar>
<div class="import-workflow-dashboard">
<v-container fluid>
<v-row>
<v-col cols="12">
<v-card class="mb-4">
<v-card-title class="d-flex align-center justify-space-between">
<div class="d-flex align-center">
<v-icon class="ml-2" color="primary">mdi-chart-dashboard</v-icon>
<span class="text-h5">داشبورد گزارشات واردات</span>
</div>
<!-- <div class="d-flex gap-2">
<v-btn color="success" @click="exportToExcel" :loading="exporting" prepend-icon="mdi-file-excel">
خروجی Excel
</v-btn>
<v-btn color="error" @click="exportToPDF" :loading="exporting" prepend-icon="mdi-file-pdf">
خروجی PDF
</v-btn>
</div> -->
</v-card-title>
</v-card>
</v-col>
</v-row>
<v-row>
<v-row style="position: relative; z-index: 999;">
<v-col cols="12">
<v-card class="mb-4">
<v-card-title>فیلترهای پیشرفته</v-card-title>
@ -48,11 +37,13 @@
<v-row>
<v-col cols="12" md="4">
<v-text-field v-model="filters.supplierSearch" label="جستجو در تامین‌کنندگان"
prepend-icon="mdi-magnify" clearable density="compact" variant="outlined"></v-text-field>
prepend-icon="mdi-magnify" clearable density="compact"
variant="outlined"></v-text-field>
</v-col>
<v-col cols="12" md="4">
<v-text-field v-model="filters.countrySearch" label="جستجو در کشور مبدأ"
prepend-icon="mdi-earth" clearable density="compact" variant="outlined"></v-text-field>
prepend-icon="mdi-earth" clearable density="compact"
variant="outlined"></v-text-field>
</v-col>
<v-col cols="12" md="4">
<v-btn color="secondary" @click="clearFilters" variant="outlined" block>

View file

@ -478,23 +478,65 @@ const isColumnVisible = (key: string) => {
const LOCAL_STORAGE_KEY = 'hesabix_storeroom_tickets_table_columns';
const printTicket = async (code: string) => {
try {
const response = await axios.post('/api/storeroom/print/ticket', {
code: code,
type: 'output'
})
window.open(`${import.meta.env.VITE_API_URL}/front/print/${response.data.id}`, '_blank', 'noreferrer')
} catch (error: any) {
const printTicket = (code: string, pdf = true, cloudePrinters = true) => {
loading.value = true;
axios.post('/api/storeroom/print/ticket', {
'code': code,
'type': 'output',
'pdf': pdf,
'printers': cloudePrinters
}).then(async (response: any) => {
try {
if (response.data && response.data.id) {
const pdfResponse = await axios({
method: 'get',
url: '/front/print/' + response.data.id,
responseType: 'arraybuffer'
});
var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
var fileLink = document.createElement('a');
fileLink.href = fileURL;
fileLink.setAttribute('download', `فاکتور انبار ${code}.pdf`);
document.body.appendChild(fileLink);
fileLink.click();
} else {
throw new Error('خطا در دریافت شناسه چاپ');
}
} catch (error) {
console.error('خطا در دریافت فایل PDF:', error);
if (error?.response?.data?.message) {
Swal.fire({
text: error?.response?.data?.message,
icon: 'warning',
confirmButtonText: 'قبول'
});
} else {
Swal.fire({
text: 'خطا در دریافت فایل PDF',
icon: 'error',
confirmButtonText: 'قبول'
});
}
} finally {
loading.value = false;
}
}).catch((error) => {
loading.value = false;
if (error?.response?.data?.message) {
Swal.fire({
text: error?.response?.data?.message,
icon: 'warning',
confirmButtonText: 'قبول'
});
} else {
Swal.fire({
text: 'خطا در ایجاد نسخه PDF',
icon: 'error',
confirmButtonText: 'قبول'
});
}
console.error('Error printing ticket:', error)
}
});
}
const loadColumnSettings = () => {

View file

@ -244,23 +244,65 @@
const LOCAL_STORAGE_KEY = 'hesabix_storeroom_tickets_table_columns';
const printTicket = async (code: string) => {
try {
const response = await axios.post('/api/storeroom/print/ticket', {
code: code,
type: 'output'
})
window.open(`${import.meta.env.VITE_API_URL}/front/print/${response.data.id}`, '_blank', 'noreferrer')
} catch (error: any) {
const printTicket = (code: string, pdf = true, cloudePrinters = true) => {
loading.value = true;
axios.post('/api/storeroom/print/ticket', {
'code': code,
'type': 'output',
'pdf': pdf,
'printers': cloudePrinters
}).then(async (response: any) => {
try {
if (response.data && response.data.id) {
const pdfResponse = await axios({
method: 'get',
url: '/front/print/' + response.data.id,
responseType: 'arraybuffer'
});
var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
var fileLink = document.createElement('a');
fileLink.href = fileURL;
fileLink.setAttribute('download', `فاکتور انبار ${code}.pdf`);
document.body.appendChild(fileLink);
fileLink.click();
} else {
throw new Error('خطا در دریافت شناسه چاپ');
}
} catch (error) {
console.error('خطا در دریافت فایل PDF:', error);
if (error?.response?.data?.message) {
Swal.fire({
text: error?.response?.data?.message,
icon: 'warning',
confirmButtonText: 'قبول'
});
} else {
Swal.fire({
text: 'خطا در دریافت فایل PDF',
icon: 'error',
confirmButtonText: 'قبول'
});
}
} finally {
loading.value = false;
}
}).catch((error) => {
loading.value = false;
if (error?.response?.data?.message) {
Swal.fire({
text: error?.response?.data?.message,
icon: 'warning',
confirmButtonText: 'قبول'
});
} else {
Swal.fire({
text: 'خطا در ایجاد نسخه PDF',
icon: 'error',
confirmButtonText: 'قبول'
});
}
console.error('Error printing ticket:', error)
}
});
}
const loadColumnSettings = () => {

View file

@ -132,23 +132,65 @@ const loadData = async () => {
}
}
const printInvoice = async () => {
try {
const response = await axios.post('/api/storeroom/print/ticket', {
code: router.currentRoute.value.params.id,
type: item.value.ticket.type
})
window.open(`${import.meta.env.VITE_API_URL}/front/print/${response.data.id}`, '_blank', 'noreferrer')
} catch (error: any) {
const printInvoice = (pdf = true, cloudePrinters = true) => {
loading.value = true;
axios.post('/api/storeroom/print/ticket', {
'code': router.currentRoute.value.params.id,
'type': item.value.ticket.type,
'pdf': pdf,
'printers': cloudePrinters
}).then(async (response: any) => {
try {
if (response.data && response.data.id) {
const pdfResponse = await axios({
method: 'get',
url: '/front/print/' + response.data.id,
responseType: 'arraybuffer'
});
var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
var fileLink = document.createElement('a');
fileLink.href = fileURL;
fileLink.setAttribute('download', `فاکتور انبار ${router.currentRoute.value.params.id}.pdf`);
document.body.appendChild(fileLink);
fileLink.click();
} else {
throw new Error('خطا در دریافت شناسه چاپ');
}
} catch (error) {
console.error('خطا در دریافت فایل PDF:', error);
if (error?.response?.data?.message) {
Swal.fire({
text: error?.response?.data?.message,
icon: 'warning',
confirmButtonText: 'قبول'
});
} else {
Swal.fire({
text: 'خطا در دریافت فایل PDF',
icon: 'error',
confirmButtonText: 'قبول'
});
}
} finally {
loading.value = false;
}
}).catch((error) => {
loading.value = false;
if (error?.response?.data?.message) {
Swal.fire({
text: error?.response?.data?.message,
icon: 'warning',
confirmButtonText: 'قبول'
});
} else {
Swal.fire({
text: 'خطا در ایجاد نسخه PDF',
icon: 'error',
confirmButtonText: 'قبول'
});
}
console.error('Error printing invoice:', error)
}
});
}
const getStatusColor = (status: string) => {