fix some bugs
This commit is contained in:
parent
15d2f40e5d
commit
8d11485530
|
@ -134,6 +134,18 @@ class ApprovalController extends AbstractController
|
|||
$document->setIsApproved(true);
|
||||
$document->setApprovedBy($user);
|
||||
|
||||
$payments = [];
|
||||
foreach ($document->getRelatedDocs() as $relatedDoc) {
|
||||
if ($relatedDoc->getType() === 'sell_receive') {
|
||||
$payments[] = $relatedDoc;
|
||||
}
|
||||
}
|
||||
foreach ($payments as $payment) {
|
||||
$payment->setIsPreview(false);
|
||||
$payment->setIsApproved(true);
|
||||
$payment->setApprovedBy($user);
|
||||
}
|
||||
|
||||
$entityManager->persist($document);
|
||||
$entityManager->flush();
|
||||
|
||||
|
|
|
@ -263,6 +263,16 @@ class BusinessController extends AbstractController
|
|||
$business->setFinancialApprover($params['financialApprover']);
|
||||
}
|
||||
|
||||
if (array_key_exists('requireWarrantyOnDelivery', $params)) {
|
||||
$business->setRequireWarrantyOnDelivery($params['requireWarrantyOnDelivery']);
|
||||
}
|
||||
if (array_key_exists('activationGraceDays', $params)) {
|
||||
$business->setActivationGraceDays($params['activationGraceDays']);
|
||||
}
|
||||
if (array_key_exists('matchWarrantyToSerial', $params)) {
|
||||
$business->setMatchWarrantyToSerial($params['matchWarrantyToSerial']);
|
||||
}
|
||||
|
||||
//get Money type
|
||||
if (!array_key_exists('arzmain', $params) && $isNew) {
|
||||
return $this->json(['result' => 2]);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Business;
|
||||
use App\Service\AccountingPermissionService;
|
||||
use App\Service\Jdate;
|
||||
use App\Service\Log;
|
||||
|
@ -73,7 +74,7 @@ class SellController extends AbstractController
|
|||
{
|
||||
$acc = $access->hasRole('sell');
|
||||
if (!$acc) throw $this->createAccessDeniedException();
|
||||
$doc = $entityManager->getRepository(\App\Entity\HesabdariDoc::class)->findOneBy([
|
||||
$doc = $entityManager->getRepository(HesabdariDoc::class)->findOneBy([
|
||||
'bid' => $acc['bid'],
|
||||
'code' => $code,
|
||||
'money' => $acc['money']
|
||||
|
@ -90,7 +91,7 @@ class SellController extends AbstractController
|
|||
{
|
||||
$acc = $access->hasRole('sell');
|
||||
if (!$acc) throw $this->createAccessDeniedException();
|
||||
$paymentDoc = $entityManager->getRepository(\App\Entity\HesabdariDoc::class)->findOneBy([
|
||||
$paymentDoc = $entityManager->getRepository(HesabdariDoc::class)->findOneBy([
|
||||
'bid' => $acc['bid'],
|
||||
'code' => $code,
|
||||
'money' => $acc['money'],
|
||||
|
@ -333,7 +334,7 @@ class SellController extends AbstractController
|
|||
$entityManager->persist($hesabdariRow);
|
||||
|
||||
// Two-step approval: اگر کسبوکار تأیید دو مرحلهای را الزامی کرده باشد
|
||||
$business = $entityManager->getRepository(\App\Entity\Business::class)->find($acc['bid']);
|
||||
$business = $entityManager->getRepository(Business::class)->find($acc['bid']);
|
||||
$businessRequire = $business && method_exists($business, 'isRequireTwoStepApproval') ? (bool)$business->isRequireTwoStepApproval() : false;
|
||||
if ($businessRequire) {
|
||||
$doc->setIsPreview(true);
|
||||
|
@ -847,10 +848,13 @@ class SellController extends AbstractController
|
|||
$accountStatus['label'] = 'بدهکار';
|
||||
$accountStatus['value'] = $bd - $bs;
|
||||
}
|
||||
// فقط در صورت تایید نهایی مجاز به چاپ هستیم
|
||||
if ($doc->getStatus() !== 'approved') {
|
||||
|
||||
$business = $entityManager->getRepository(Business::class)->find($acc['bid']);
|
||||
$twoApproval = $business && method_exists($business, 'isRequireTwoStepApproval') ? (bool)$business->isRequireTwoStepApproval() : false;
|
||||
if ($twoApproval && $doc->isApproved() !== true && $doc->isPreview() == true) {
|
||||
return $this->json(['result' => -10, 'message' => 'فاکتور هنوز تایید نشده است'], 403);
|
||||
}
|
||||
|
||||
if ($params['pdf'] == true || $params['printers'] == true) {
|
||||
$note = '';
|
||||
if ($printSettings) {
|
||||
|
@ -1261,7 +1265,7 @@ class SellController extends AbstractController
|
|||
$entityManager->persist($hesabdariRow);
|
||||
|
||||
// Two-step approval: اگر کسبوکار تأیید دو مرحلهای را الزامی کرده باشد
|
||||
$business = $entityManager->getRepository(\App\Entity\Business::class)->find($acc['bid']);
|
||||
$business = $entityManager->getRepository(Business::class)->find($acc['bid']);
|
||||
$businessRequire = $business && method_exists($business, 'isRequireTwoStepApproval') ? (bool)$business->isRequireTwoStepApproval() : false;
|
||||
if ($businessRequire) {
|
||||
$doc->setIsPreview(true);
|
||||
|
@ -1299,6 +1303,8 @@ class SellController extends AbstractController
|
|||
$paymentDoc->setDate($params['invoiceDate']);
|
||||
$paymentDoc->setDes($payment['description'] ?? 'دریافت وجه فاکتور فروش شماره ' . $doc->getCode());
|
||||
$paymentDoc->setAmount($payment['amount']);
|
||||
$paymentDoc->setIsPreview(true);
|
||||
$paymentDoc->setIsApproved(false);
|
||||
|
||||
// ایجاد ارتباط با فاکتور اصلی
|
||||
$doc->addRelatedDoc($paymentDoc);
|
||||
|
|
|
@ -238,6 +238,9 @@ class StoreroomController extends AbstractController
|
|||
]);
|
||||
$sellsForExport = [];
|
||||
foreach ($sells as $sell) {
|
||||
if ($sell->isPreview()) {
|
||||
continue;
|
||||
}
|
||||
$temp = $provider->Entity2Array($sell, 0);
|
||||
$person = $this->getPerson($sell);
|
||||
if ($person) {
|
||||
|
@ -263,6 +266,9 @@ class StoreroomController extends AbstractController
|
|||
]);
|
||||
$rfsellsForExport = [];
|
||||
foreach ($rfsells as $sell) {
|
||||
if ($sell->isPreview()) {
|
||||
continue;
|
||||
}
|
||||
$temp = $provider->Entity2Array($sell, 0);
|
||||
$person = $this->getPerson($sell);
|
||||
if ($person) {
|
||||
|
@ -288,6 +294,9 @@ class StoreroomController extends AbstractController
|
|||
]);
|
||||
$rfbuysForExport = [];
|
||||
foreach ($rfbuys as $buy) {
|
||||
if ($buy->isPreview()) {
|
||||
continue;
|
||||
}
|
||||
$temp = $provider->Entity2Array($buy, 0);
|
||||
$person = $this->getPerson($buy);
|
||||
if ($person) {
|
||||
|
@ -910,12 +919,12 @@ class StoreroomController extends AbstractController
|
|||
|
||||
$business = $entityManager->getRepository(\App\Entity\Business::class)->find($acc['bid']);
|
||||
$businessRequire = $business && method_exists($business, 'isRequireTwoStepApproval') ? (bool)$business->isRequireTwoStepApproval() : false;
|
||||
if ($businessRequire) {
|
||||
// بررسی وضعیت تأیید از طریق StoreroomTicket
|
||||
if ($businessRequire && $doc->isApproved() !== true && $doc->isPreview() == true) {
|
||||
if ($doc->isPreview()) {
|
||||
return $this->json(['result' => -10, 'message' => 'حواله هنوز تایید نشده است'], 403);
|
||||
}
|
||||
}
|
||||
|
||||
$pdfPid = 0;
|
||||
$pdfPid = $provider->createPrint(
|
||||
$acc['bid'],
|
||||
|
|
|
@ -584,6 +584,9 @@ class Explore
|
|||
'financialApprover' => $item->getFinancialApprover(),
|
||||
'updateSellPrice' => $item->isCommodityUpdateSellPriceAuto(),
|
||||
'updateBuyPrice' => $item->isCommodityUpdateBuyPriceAuto(),
|
||||
'requireWarrantyOnDelivery' => $item->getRequireWarrantyOnDelivery(),
|
||||
'activationGraceDays' => $item->getActivationGraceDays(),
|
||||
'matchWarrantyToSerial' => $item->getMatchWarrantyToSerial(),
|
||||
];
|
||||
if (!$item->getProfitCalctype()) {
|
||||
$res['profitCalcType'] = 'lis';
|
||||
|
|
|
@ -507,6 +507,7 @@ const fa_lang = {
|
|||
basic_info: "اطلاعات پایه",
|
||||
year_label: "سال مالی جاری",
|
||||
global_settings: "تنظیمات سراسری",
|
||||
warranty_settings: "تنظیمات گارانتی",
|
||||
gate_pay: "درگاه پرداخت",
|
||||
a4l: "کاغذ A4 افقی",
|
||||
a4p: "کاغذ A4 عمودی",
|
||||
|
|
|
@ -892,6 +892,12 @@ const router = createRouter({
|
|||
'login': true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'plugins/warranty/intro',
|
||||
name: 'plugin_warranty_intro',
|
||||
component: () =>
|
||||
import('../views/acc/plugins/warranty/intro.vue'),
|
||||
},
|
||||
{
|
||||
path: 'notifications/list',
|
||||
name: 'notification_list',
|
||||
|
@ -1080,6 +1086,12 @@ const router = createRouter({
|
|||
'login': true,
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'plugins/import-workflow/intro',
|
||||
name: 'import_workflow_intro',
|
||||
component: () =>
|
||||
import('../views/acc/plugins/import-workflow/intro.vue'),
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
195
webUI/src/views/acc/plugins/import-workflow/intro.vue
Normal file
195
webUI/src/views/acc/plugins/import-workflow/intro.vue
Normal file
|
@ -0,0 +1,195 @@
|
|||
<template>
|
||||
<div class="plugin-intro">
|
||||
<div class="intro-header">
|
||||
<div class="plugin-icon">
|
||||
<i class="fas fa-ship"></i>
|
||||
</div>
|
||||
<div class="plugin-info">
|
||||
<h1>افزونه مدیریت واردات کالا</h1>
|
||||
<p class="plugin-description">
|
||||
مدیریت پروندههای واردات از ثبت تا ترخیص: اسناد، اقلام، پرداختها، حمل و مراحل
|
||||
</p>
|
||||
<div class="plugin-version">
|
||||
<span class="version-badge">نسخه 1.0.0</span>
|
||||
<span v-if="isPluginActive('importWorkflow')" class="status-badge active">فعال</span>
|
||||
<RouterLink to="/acc/plugin-center/view-end/import-workflow" v-if="!isPluginActive('importWorkflow')">
|
||||
<span class="status-badge active text-white d-flex align-items-center">
|
||||
<i class="fa fa-shopping-cart me-1"></i>
|
||||
خرید
|
||||
</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="intro-content">
|
||||
<div class="features-section">
|
||||
<h2>امکانات افزونه</h2>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-folder-plus"></i>
|
||||
</div>
|
||||
<h3>پرونده واردات</h3>
|
||||
<p>ایجاد و مدیریت پروندههای واردات با کد یکتا و وضعیت</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-file-alt"></i>
|
||||
</div>
|
||||
<h3>مدیریت اسناد</h3>
|
||||
<p>بارگذاری و سازماندهی اسناد (پروفرما، پکینگ، حواله، ترخیص و ...)</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-boxes"></i>
|
||||
</div>
|
||||
<h3>اقلام و جزئیات</h3>
|
||||
<p>ثبت اقلام، ارزش، وزن، حجم، برند، مدل و مشخصات کالا</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-money-bill-wave"></i>
|
||||
</div>
|
||||
<h3>پرداختها و هزینهها</h3>
|
||||
<p>مدیریت پرداختها، ارز، نرخ تبدیل و هزینههای مرتبط</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-truck-loading"></i>
|
||||
</div>
|
||||
<h3>حمل و لجستیک</h3>
|
||||
<p>ثبت اطلاعات حمل، کانتینر، مسیر و تاریخها</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-stream"></i>
|
||||
</div>
|
||||
<h3>مراحل و پیگیری</h3>
|
||||
<p>تعریف مراحل، وضعیتها، یادداشتها و پیگیری پیشرفت</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="validation-section">
|
||||
<h2>کنترلها</h2>
|
||||
<div class="validation-list">
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>کنترل کامل اطلاعات موردنیاز ترخیص</span>
|
||||
</div>
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>همگامسازی اقلام با موجودی و کد کالا</span>
|
||||
</div>
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>گزارشگیری از هزینهها و وضعیت پرونده</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setup-section">
|
||||
<h2>مراحل راهاندازی</h2>
|
||||
<div class="setup-steps">
|
||||
<div class="setup-step">
|
||||
<div class="step-number">1</div>
|
||||
<div class="step-content">
|
||||
<h4>فعالسازی افزونه</h4>
|
||||
<p>افزونه را از مرکز افزونهها فعال کنید</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setup-step">
|
||||
<div class="step-number">2</div>
|
||||
<div class="step-content">
|
||||
<h4>ایجاد پرونده</h4>
|
||||
<p>پرونده جدید واردات ایجاد و مشخصات پایه را ثبت کنید</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setup-step">
|
||||
<div class="step-number">3</div>
|
||||
<div class="step-content">
|
||||
<h4>ثبت اسناد و اقلام</h4>
|
||||
<p>اسناد، اقلام، پرداختها و حمل را به پرونده اضافه کنید</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="intro-footer">
|
||||
<div v-if="isPluginActive('importWorkflow')" class="action-buttons">
|
||||
<router-link to="/acc/plugins/import-workflow/list" class="btn btn-success">
|
||||
<i class="fas fa-list"></i>
|
||||
ورود به مدیریت واردات
|
||||
</router-link>
|
||||
</div>
|
||||
<div style="margin-top: 20px; font-size: 0.75rem; color: #888; text-align: center;">
|
||||
Developed by <a href="https://pirouz.xyz" target="_blank" style="color: #667eea; text-decoration: none;">Mohammad Rezai</a> – 2025
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: 'ImportWorkflowIntro',
|
||||
data() {
|
||||
return {
|
||||
plugins: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isPluginActive(plugName) {
|
||||
return this.plugins && this.plugins[plugName] !== undefined;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
axios.post('/api/plugin/get/actives').then((response) => {
|
||||
this.plugins = response.data;
|
||||
});
|
||||
if (this.$store) {
|
||||
this.$store.commit('setPageTitle', 'مدیریت واردات کالا - معرفی افزونه')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* reuse tax intro styles for consistent look */
|
||||
.plugin-intro { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||
.intro-header { display: flex; align-items: center; gap: 20px; margin-bottom: 40px; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white; }
|
||||
.plugin-icon { font-size: 3rem; background: rgba(255, 255, 255, 0.2); width: 80px; height: 80px; display: flex; align-items: center; justify-content: center; border-radius: 50%; flex-shrink: 0; }
|
||||
.plugin-info h1 { margin: 0 0 10px 0; font-size: 2.5rem; font-weight: 700; }
|
||||
.plugin-description { font-size: 1.1rem; margin: 0 0 15px 0; opacity: 0.9; }
|
||||
.plugin-version { display: flex; gap: 10px; }
|
||||
.version-badge, .status-badge { padding: 5px 12px; border-radius: 20px; font-size: 0.9rem; font-weight: 600; }
|
||||
.version-badge { background: rgba(255, 255, 255, 0.2); }
|
||||
.status-badge.active { background: #28a745; }
|
||||
.intro-content { display: flex; flex-direction: column; gap: 40px; }
|
||||
.features-section, .invoice-types-section, .validation-section, .setup-section, .compliance-section { background: white; border-radius: 15px; padding: 30px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); }
|
||||
.features-section h2, .invoice-types-section h2, .validation-section h2, .setup-section h2, .compliance-section h2 { margin: 0 0 25px 0; font-size: 1.8rem; color: #333; border-bottom: 3px solid #667eea; padding-bottom: 10px; }
|
||||
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 25px; }
|
||||
.feature-card { padding: 25px; border-radius: 12px; background: #f8f9fa; border-left: 4px solid #667eea; transition: transform 0.3s ease, box-shadow 0.3s ease; }
|
||||
.feature-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); }
|
||||
.feature-icon { font-size: 2rem; color: #667eea; margin-bottom: 15px; width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; background: rgba(102, 126, 234, 0.1); border-radius: 50%; }
|
||||
.validation-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 15px; }
|
||||
.validation-item { display: flex; align-items: center; gap: 12px; padding: 15px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #28a745; }
|
||||
.setup-steps { display: flex; flex-direction: column; gap: 20px; }
|
||||
.setup-step { display: flex; align-items: flex-start; gap: 20px; padding: 20px; background: #f8f9fa; border-radius: 12px; border-left: 4px solid #667eea; }
|
||||
.step-number { background: #667eea; color: white; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 1.2rem; flex-shrink: 0; }
|
||||
.action-buttons { display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; }
|
||||
.btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600; transition: all 0.3s ease; border: none; cursor: pointer; }
|
||||
.btn-success { background: #28a745; color: white; }
|
||||
.btn-success:hover { background: #218838; transform: translateY(-2px); }
|
||||
@media (max-width: 768px) { .plugin-intro { padding: 15px; } .intro-header { flex-direction: column; text-align: center; padding: 20px; gap: 15px; } .plugin-icon { width: 60px; height: 60px; font-size: 2rem; } .plugin-info h1 { font-size: 1.8rem; } .features-section, .invoice-types-section, .validation-section, .setup-section, .compliance-section { padding: 20px; } .features-grid { grid-template-columns: 1fr; gap: 20px; } .feature-card { padding: 20px; } .feature-icon { width: 50px; height: 50px; font-size: 1.5rem; } .action-buttons { flex-direction: column; gap: 15px; } .btn { justify-content: center; padding: 15px 20px; font-size: 1rem; } }
|
||||
</style>
|
||||
|
||||
|
|
@ -127,141 +127,58 @@
|
|||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-card>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="serials"
|
||||
:loading="loading"
|
||||
density="comfortable"
|
||||
class="elevation-1"
|
||||
:header-props="{ class: 'custom-header' }"
|
||||
hover
|
||||
show-select
|
||||
v-model="selectedItems"
|
||||
item-key="id"
|
||||
return-object
|
||||
:items-per-page="50"
|
||||
>
|
||||
<v-data-table :headers="headers" :items="serials" :loading="loading" density="comfortable"
|
||||
class="elevation-1" :header-props="{ class: 'custom-header' }" hover show-select v-model="selectedItems"
|
||||
item-key="id" return-object :items-per-page="50">
|
||||
<template #top>
|
||||
<div class="d-block d-md-none pa-4">
|
||||
<div class="d-flex gap-2 flex-column mb-3">
|
||||
<v-btn
|
||||
v-if="selectedItems.length > 0"
|
||||
color="error"
|
||||
prepend-icon="mdi-delete-multiple"
|
||||
@click="showDeleteBulkDialog = true"
|
||||
size="small"
|
||||
block
|
||||
>
|
||||
حذف انتخاب شدهها <v-chip size="small" color="error" variant="tonal" class="ms-2" style="color: white !important;">{{ selectedItems.length }}</v-chip>
|
||||
<v-btn v-if="selectedItems.length > 0" color="error" prepend-icon="mdi-delete-multiple"
|
||||
@click="showDeleteBulkDialog = true" size="small" block>
|
||||
حذف انتخاب شدهها <v-chip size="small" color="error" variant="tonal" class="ms-2"
|
||||
style="color: white !important;">{{ selectedItems.length }}</v-chip>
|
||||
</v-btn>
|
||||
<v-btn color="primary" prepend-icon="mdi-plus" @click="addSerial" size="small" block>
|
||||
افزودن سریال
|
||||
</v-btn>
|
||||
<v-btn color="secondary" prepend-icon="mdi-upload" @click="showBulkImportDialog = true" size="small" block>
|
||||
<v-btn color="secondary" prepend-icon="mdi-upload" @click="showBulkImportDialog = 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="loadSerials"
|
||||
/>
|
||||
<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="loadSerials" />
|
||||
<div class="d-flex gap-2 mb-3">
|
||||
<v-select
|
||||
v-model="filters.status"
|
||||
label="وضعیت"
|
||||
:items="statusOptions"
|
||||
clearable
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
style="flex: 1;"
|
||||
@update:model-value="loadSerials"
|
||||
/>
|
||||
<v-select
|
||||
v-model="filters.commodity_id"
|
||||
label="محصول"
|
||||
:items="commodities"
|
||||
item-title="name"
|
||||
item-value="id"
|
||||
clearable
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
style="flex: 1;"
|
||||
@update:model-value="loadSerials"
|
||||
/>
|
||||
<v-select v-model="filters.status" label="وضعیت" :items="statusOptions" clearable density="compact"
|
||||
variant="outlined" hide-details style="flex: 1;" @update:model-value="loadSerials" />
|
||||
<v-select v-model="filters.commodity_id" label="محصول" :items="commodities" item-title="name"
|
||||
item-value="id" clearable density="compact" variant="outlined" hide-details style="flex: 1;"
|
||||
@update:model-value="loadSerials" />
|
||||
</div>
|
||||
</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="loadSerials"
|
||||
class="ml-2"
|
||||
/>
|
||||
<v-select
|
||||
v-model="filters.status"
|
||||
label="وضعیت"
|
||||
:items="statusOptions"
|
||||
clearable
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
style="max-width: 220px;"
|
||||
@update:model-value="loadSerials"
|
||||
class="ml-2"
|
||||
/>
|
||||
<v-select
|
||||
v-model="filters.commodity_id"
|
||||
label="محصول"
|
||||
:items="commodities"
|
||||
item-title="name"
|
||||
item-value="id"
|
||||
clearable
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
style="max-width: 250px;"
|
||||
@update:model-value="loadSerials"
|
||||
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="loadSerials" class="ml-2" />
|
||||
<v-select v-model="filters.status" label="وضعیت" :items="statusOptions" clearable density="compact"
|
||||
variant="outlined" hide-details style="max-width: 220px;" @update:model-value="loadSerials"
|
||||
class="ml-2" />
|
||||
<v-select v-model="filters.commodity_id" label="محصول" :items="commodities" item-title="name"
|
||||
item-value="id" clearable density="compact" variant="outlined" hide-details
|
||||
style="max-width: 250px;" @update:model-value="loadSerials" class="ml-2" />
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
variant="tonal"
|
||||
prepend-icon="mdi-cog"
|
||||
class="ml-2"
|
||||
@click="openSettings"
|
||||
>
|
||||
تنظیمات
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-if="selectedItems.length > 0"
|
||||
color="error"
|
||||
prepend-icon="mdi-delete-multiple"
|
||||
@click="showDeleteBulkDialog = true"
|
||||
class="ml-2"
|
||||
>
|
||||
حذف انتخاب شدهها <v-chip size="small" color="error" variant="tonal" class="ms-2" style="color: red !important;">{{ selectedItems.length }}</v-chip>
|
||||
<v-btn v-if="selectedItems.length > 0" color="error" prepend-icon="mdi-delete-multiple"
|
||||
@click="showDeleteBulkDialog = true" class="ml-2">
|
||||
حذف انتخاب شدهها <v-chip size="small" color="error" variant="tonal" class="ms-2"
|
||||
style="color: red !important;">{{ selectedItems.length }}</v-chip>
|
||||
</v-btn>
|
||||
<v-btn color="primary" prepend-icon="mdi-plus" @click="addSerial">
|
||||
افزودن سریال
|
||||
</v-btn>
|
||||
<v-btn color="secondary" prepend-icon="mdi-upload" @click="showBulkImportDialog = true" class="ml-2">
|
||||
<v-btn color="secondary" prepend-icon="mdi-upload" @click="showBulkImportDialog = true"
|
||||
class="ml-2">
|
||||
وارد کردن انبوه
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
|
@ -293,20 +210,15 @@
|
|||
<span>
|
||||
{{ (item as any).warrantyEndDate ? formatDate((item as any).warrantyEndDate) : '-' }}
|
||||
</span>
|
||||
<v-chip
|
||||
v-if="(item as any).expired"
|
||||
color="error"
|
||||
size="x-small"
|
||||
variant="flat"
|
||||
class="ms-2"
|
||||
>
|
||||
<v-chip v-if="(item as any).expired" color="error" size="x-small" variant="flat" class="ms-2">
|
||||
منقضی
|
||||
</v-chip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #item.commodity="{ item }">
|
||||
<v-btn variant="text" color="primary" size="small" @click="viewCommodity((item as any).commodity)" class="text-none">
|
||||
<v-btn variant="text" color="primary" size="small" @click="viewCommodity((item as any).commodity)"
|
||||
class="text-none">
|
||||
{{ (item as any).commodity?.name || 'نامشخص' }}
|
||||
</v-btn>
|
||||
</template>
|
||||
|
@ -338,26 +250,13 @@
|
|||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<SerialDialog
|
||||
v-model="showAddDialog"
|
||||
:serial="selectedSerial"
|
||||
:commodities="commodities"
|
||||
@save="saveSerial"
|
||||
@close="closeDialog"
|
||||
/>
|
||||
<SerialDialog v-model="showAddDialog" :serial="selectedSerial" :commodities="commodities" @save="saveSerial"
|
||||
@close="closeDialog" />
|
||||
|
||||
<SerialViewDialog
|
||||
v-model="showViewDialog"
|
||||
:serial="selectedSerial"
|
||||
@close="closeViewDialog"
|
||||
/>
|
||||
<SerialViewDialog v-model="showViewDialog" :serial="selectedSerial" @close="closeViewDialog" />
|
||||
|
||||
<BulkImportDialog
|
||||
v-model="showBulkImportDialog"
|
||||
:commodities="commodities"
|
||||
@import="bulkImport"
|
||||
@close="closeBulkImportDialog"
|
||||
/>
|
||||
<BulkImportDialog v-model="showBulkImportDialog" :commodities="commodities" @import="bulkImport"
|
||||
@close="closeBulkImportDialog" />
|
||||
|
||||
<v-dialog v-model="showDeleteDialog" max-width="400">
|
||||
<v-card>
|
||||
|
@ -387,55 +286,10 @@
|
|||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-dialog v-model="showSettingsDialog" max-width="500">
|
||||
<v-card :loading="settingsLoading || loading">
|
||||
<v-toolbar color="primary" flat>
|
||||
<v-icon color="white" class="ms-2">mdi-cog</v-icon>
|
||||
<v-toolbar-title class="text-white text-subtitle-1">تنظیمات گارانتی</v-toolbar-title>
|
||||
<v-spacer />
|
||||
<v-btn icon @click="showSettingsDialog = false">
|
||||
<v-icon color="white">mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-switch
|
||||
v-model="settings.requireWarrantyOnDelivery"
|
||||
label="الزام ثبت گارانتی هنگام صدور حواله"
|
||||
color="primary"
|
||||
inset
|
||||
hide-details
|
||||
:disabled="settingsLoading || loading"
|
||||
/>
|
||||
<v-switch
|
||||
v-model="settings.matchWarrantyToSerial"
|
||||
label="تطبیق خودکار گارانتی با سریال کالا (در صورت یکسان بودن کد)"
|
||||
color="primary"
|
||||
inset
|
||||
hide-details
|
||||
class="mt-2"
|
||||
:disabled="settingsLoading || loading"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model.number="settings.activationGraceDays"
|
||||
type="number"
|
||||
min="0"
|
||||
label="مهلت فعالسازی گارانتی (روز)"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
hide-details
|
||||
class="mt-4"
|
||||
:disabled="settingsLoading || loading"
|
||||
/>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="grey" variant="text" @click="showSettingsDialog = false">انصراف</v-btn>
|
||||
<v-btn color="primary" :loading="loading" :disabled="settingsLoading" @click="saveSettings">ذخیره</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<!-- تنظیمات گارانتی به تب تنظیمات کسبوکار منتقل شد -->
|
||||
|
||||
<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' }}
|
||||
|
@ -880,27 +734,34 @@ onMounted(async () => {
|
|||
.warranty-plugin {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.v-data-table {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
:deep(.v-data-table-header th) {
|
||||
background-color: #f5f5f5 !important;
|
||||
font-weight: bold !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
:deep(.v-data-table__wrapper table td) {
|
||||
padding: 12px 16px !important;
|
||||
border-bottom: 1px solid #e0e0e0 !important;
|
||||
}
|
||||
|
||||
:deep(.v-data-table__wrapper table tr:hover) {
|
||||
background-color: #f8f9fa !important;
|
||||
}
|
||||
|
||||
:deep(.v-chip) {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.custom-header {
|
||||
background-color: #f5f5f5 !important;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
|
@ -916,18 +777,22 @@ onMounted(async () => {
|
|||
gap: 16px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.stats-card:focus {
|
||||
outline: 2px solid rgba(255, 255, 255, 0.5);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.stats-card.active-filter {
|
||||
transform: translateY(-4px) scale(1.02);
|
||||
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2);
|
||||
border: 2px solid rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.stats-card.active-filter::before {
|
||||
background: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%);
|
||||
}
|
||||
|
||||
.stats-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
|
@ -939,10 +804,12 @@ onMounted(async () => {
|
|||
border-radius: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.stats-card:hover {
|
||||
transform: translateY(-8px) scale(1.01);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stats-icon {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
@ -951,11 +818,13 @@ onMounted(async () => {
|
|||
padding: 12px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.stats-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stats-number {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
|
@ -963,24 +832,30 @@ onMounted(async () => {
|
|||
margin-bottom: 4px;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.stats-label {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
opacity: 0.9;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.total-card {
|
||||
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
|
||||
}
|
||||
|
||||
.active-card {
|
||||
background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
|
||||
}
|
||||
|
||||
.expired-card {
|
||||
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
|
||||
}
|
||||
|
||||
.inactive-card {
|
||||
background: linear-gradient(135deg, #95a5a6 0%, #7f8c8d 100%);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.stats-card {
|
||||
flex-direction: column;
|
||||
|
|
224
webUI/src/views/acc/plugins/warranty/intro.vue
Normal file
224
webUI/src/views/acc/plugins/warranty/intro.vue
Normal file
|
@ -0,0 +1,224 @@
|
|||
<template>
|
||||
<div class="plugin-intro">
|
||||
<div class="intro-header">
|
||||
<div class="plugin-icon">
|
||||
<i class="fas fa-shield-alt"></i>
|
||||
</div>
|
||||
<div class="plugin-info">
|
||||
<h1>افزونه مدیریت گارانتی</h1>
|
||||
<p class="plugin-description">
|
||||
مدیریت چرخهعمر گارانتی از ثبت سریال تا تخصیص، اسکن، ارسال برای مشتری و فعالسازی آنلاین
|
||||
</p>
|
||||
<div class="plugin-version">
|
||||
<span class="version-badge">نسخه 1.0.0</span>
|
||||
<span v-if="isPluginActive('warranty')" class="status-badge active">فعال</span>
|
||||
<RouterLink to="/acc/plugin-center/view-end/warranty" v-if="!isPluginActive('warranty')">
|
||||
<span class="status-badge active text-white d-flex align-items-center">
|
||||
<i class="fa fa-shopping-cart me-1"></i>
|
||||
خرید
|
||||
</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="intro-content">
|
||||
<div class="features-section">
|
||||
<h2>امکانات افزونه</h2>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i class="fas fa-barcode"></i></div>
|
||||
<h3>مدیریت سریال گارانتی</h3>
|
||||
<p>ثبت/ویرایش سریال، جستجو و فیلتر بر اساس وضعیت، تاریخ شروع/پایان و کالا</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i class="fas fa-file-import"></i></div>
|
||||
<h3>واردسازی انبوه با پیشنمایش</h3>
|
||||
<p>پیشنمایش فایل و واردسازی انبوه سریالها (CSV/Excel) با اعتبارسنجی</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i class="fas fa-link"></i></div>
|
||||
<h3>تخصیص خودکار به فروش</h3>
|
||||
<p>تخصیص سریالهای «آزاد» به اقلام حواله خروج بر اساس کالا و تعداد موردنیاز</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i class="fas fa-qrcode"></i></div>
|
||||
<h3>اسکن و تأیید انبار</h3>
|
||||
<p>اسکن سریال در خروج از انبار و تأیید صحت کالا پیش از خروج (Verified)</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i class="fas fa-sms"></i></div>
|
||||
<h3>ارسال سریال برای خریدار</h3>
|
||||
<p>ارسال سریالهای تخصیصیافته فاکتور به خریدار از طریق پیامک</p>
|
||||
</div>
|
||||
<!-- <div class="feature-card">
|
||||
<div class="feature-icon"><i class="fas fa-chart-pie"></i></div>
|
||||
<h3>آمار و وضعیتها</h3>
|
||||
<p>گزارش تعداد سریالها بر اساس وضعیت و شمارش سریالهای منقضیشده</p>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="invoice-types-section">
|
||||
<h2>چرخه وضعیت سریال</h2>
|
||||
<div class="invoice-types-grid">
|
||||
<div class="invoice-type-card">
|
||||
<div class="type-icon info"><i class="fas fa-dot-circle"></i></div>
|
||||
<h4>آزاد</h4>
|
||||
<p>سریال ثبت شده و آماده تخصیص به فروش است</p>
|
||||
</div>
|
||||
<div class="invoice-type-card">
|
||||
<div class="type-icon primary"><i class="fas fa-link"></i></div>
|
||||
<h4>تخصیص یافته</h4>
|
||||
<p>سریال به فاکتور/سند فروش اختصاص یافته است</p>
|
||||
</div>
|
||||
<div class="invoice-type-card">
|
||||
<div class="type-icon danger"><i class="fas fa-ban"></i></div>
|
||||
<h4>باطل</h4>
|
||||
<p>سریال نامعتبر یا ابطال شده است</p>
|
||||
</div>
|
||||
<div class="invoice-type-card">
|
||||
<div class="type-icon info"><i class="fas fa-check-circle"></i></div>
|
||||
<h4>مصرفشده</h4>
|
||||
<p>سریال استفاده شده و قابل تخصیص مجدد نیست</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="validation-section">
|
||||
<h2>فعالسازی توسط مشتری</h2>
|
||||
<div class="validation-list">
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>مسیر عمومی فعالسازی: ارائه کد گارانتی توسط مشتری و اعتبارسنجی</span>
|
||||
</div>
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>مهلت فعالسازی قابل تنظیم</span>
|
||||
</div>
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>پشتیبانی از کد/رمز فعالسازی حواله برای امنیت بیشتر</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="validation-section">
|
||||
<h2>کنترلها</h2>
|
||||
<div class="validation-list">
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>جلوگیری از تخصیص تکراری سریال</span>
|
||||
</div>
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>همخوانی نوع کالا با سریال</span>
|
||||
</div>
|
||||
<div class="validation-item">
|
||||
<i class="fas fa-check text-success"></i>
|
||||
<span>مدیریت تاریخ شروع و پایان گارانتی</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setup-section">
|
||||
<h2>مراحل راهاندازی</h2>
|
||||
<div class="setup-steps">
|
||||
<div class="setup-step">
|
||||
<div class="step-number">1</div>
|
||||
<div class="step-content">
|
||||
<h4>فعالسازی افزونه</h4>
|
||||
<p>افزونه را از مرکز افزونهها فعال کنید</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setup-step">
|
||||
<div class="step-number">2</div>
|
||||
<div class="step-content">
|
||||
<h4>واردسازی سریالها</h4>
|
||||
<p>سریالها را به صورت دستی یا انبوه اضافه کنید</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setup-step">
|
||||
<div class="step-number">3</div>
|
||||
<div class="step-content">
|
||||
<h4>تخصیص به حواله خروج</h4>
|
||||
<p>سریالها را به اقلام حواله خروج تخصیص دهید</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="intro-footer">
|
||||
<div style="margin-top: 20px; font-size: 0.75rem; color: #888; text-align: center;">
|
||||
Developed by <a href="https://pirouz.xyz" target="_blank" style="color: #667eea; text-decoration: none;">Mohammad Rezai</a> – 2025
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: 'WarrantyIntro',
|
||||
data() {
|
||||
return {
|
||||
plugins: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isPluginActive(plugName) {
|
||||
return this.plugins && this.plugins[plugName] !== undefined;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
axios.post('/api/plugin/get/actives').then((response) => {
|
||||
this.plugins = response.data;
|
||||
});
|
||||
if (this.$store) {
|
||||
this.$store.commit('setPageTitle', 'مدیریت گارانتی - معرفی افزونه')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* same styles as taxsettings intro for consistent look */
|
||||
.plugin-intro { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||
.intro-header { display: flex; align-items: center; gap: 20px; margin-bottom: 40px; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white; }
|
||||
.plugin-icon { font-size: 3rem; background: rgba(255, 255, 255, 0.2); width: 80px; height: 80px; display: flex; align-items: center; justify-content: center; border-radius: 50%; flex-shrink: 0; }
|
||||
.plugin-info h1 { margin: 0 0 10px 0; font-size: 2.5rem; font-weight: 700; }
|
||||
.plugin-description { font-size: 1.1rem; margin: 0 0 15px 0; opacity: 0.9; }
|
||||
.plugin-version { display: flex; gap: 10px; }
|
||||
.version-badge, .status-badge { padding: 5px 12px; border-radius: 20px; font-size: 0.9rem; font-weight: 600; }
|
||||
.version-badge { background: rgba(255, 255, 255, 0.2); }
|
||||
.status-badge.active { background: #28a745; }
|
||||
.intro-content { display: flex; flex-direction: column; gap: 40px; }
|
||||
.features-section, .invoice-types-section, .validation-section, .setup-section, .compliance-section { background: white; border-radius: 15px; padding: 30px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); }
|
||||
.features-section h2, .invoice-types-section h2, .validation-section h2, .setup-section h2, .compliance-section h2 { margin: 0 0 25px 0; font-size: 1.8rem; color: #333; border-bottom: 3px solid #667eea; padding-bottom: 10px; }
|
||||
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 25px; }
|
||||
.feature-card { padding: 25px; border-radius: 12px; background: #f8f9fa; border-left: 4px solid #667eea; transition: transform 0.3s ease, box-shadow 0.3s ease; }
|
||||
.feature-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); }
|
||||
.feature-icon { font-size: 2rem; color: #667eea; margin-bottom: 15px; width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; background: rgba(102, 126, 234, 0.1); border-radius: 50%; }
|
||||
.invoice-types-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; }
|
||||
.invoice-type-card { text-align: center; padding: 25px; border-radius: 12px; background: #f8f9fa; border: 2px solid transparent; transition: all 0.3s ease; }
|
||||
.invoice-type-card:hover { border-color: #667eea; transform: translateY(-3px); }
|
||||
.type-icon { font-size: 2.5rem; margin-bottom: 15px; width: 80px; height: 80px; display: flex; align-items: center; justify-content: center; border-radius: 50%; margin: 0 auto 15px auto; }
|
||||
.type-icon.primary { background: #e3f2fd; color: #1976d2; }
|
||||
.type-icon.warning { background: #fff3e0; color: #f57c00; }
|
||||
.type-icon.info { background: #e8f5e8; color: #388e3c; }
|
||||
.validation-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 15px; }
|
||||
.validation-item { display: flex; align-items: center; gap: 12px; padding: 15px; background: #f8f9fa; border-radius: 8px; border-right: 4px solid #28a745; }
|
||||
.setup-steps { display: flex; flex-direction: column; gap: 20px; }
|
||||
.setup-step { display: flex; align-items: flex-start; gap: 20px; padding: 20px; background: #f8f9fa; border-radius: 12px; border-right: 4px solid #667eea; }
|
||||
.step-number { background: #667eea; color: white; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 1.2rem; flex-shrink: 0; }
|
||||
.action-buttons { display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; }
|
||||
.btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600; transition: all 0.3s ease; border: none; cursor: pointer; }
|
||||
.btn-success { background: #28a745; color: white; }
|
||||
.btn-success:hover { background: #218838; transform: translateY(-2px); }
|
||||
@media (max-width: 768px) { .plugin-intro { padding: 15px; } .intro-header { flex-direction: column; text-align: center; padding: 20px; gap: 15px; } .plugin-icon { width: 60px; height: 60px; font-size: 2rem; } .plugin-info h1 { font-size: 1.8rem; } .features-section, .invoice-types-section, .validation-section, .setup-section, .compliance-section { padding: 20px; } .features-grid { grid-template-columns: 1fr; gap: 20px; } .feature-card { padding: 20px; } .feature-icon { width: 50px; height: 50px; font-size: 1.5rem; } .invoice-types-grid { grid-template-columns: 1fr; gap: 15px; } .invoice-type-card { padding: 20px; } .type-icon { width: 60px; height: 60px; font-size: 2rem; } .action-buttons { flex-direction: column; gap: 15px; } .btn { justify-content: center; padding: 15px 20px; font-size: 1rem; } }
|
||||
</style>
|
||||
|
||||
|
||||
|
|
@ -4,7 +4,8 @@
|
|||
<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" />
|
||||
<v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text"
|
||||
icon="mdi-arrow-right" />
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
|
@ -21,14 +22,8 @@
|
|||
</v-tooltip>
|
||||
<v-tooltip v-if="isPluginActive('taxsettings')" text="ارسال گروهی به کارپوشه مودیان" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
icon="mdi-cloud-upload"
|
||||
color="orange"
|
||||
@click="sendBulkToTaxSystem()"
|
||||
:disabled="itemsSelected.length === 0"
|
||||
:loading="bulkLoading"
|
||||
></v-btn>
|
||||
<v-btn v-bind="props" icon="mdi-cloud-upload" color="orange" @click="sendBulkToTaxSystem()"
|
||||
:disabled="itemsSelected.length === 0" :loading="bulkLoading"></v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-menu>
|
||||
|
@ -46,7 +41,8 @@
|
|||
</template>
|
||||
</v-list-item>
|
||||
<v-list-subheader color="primary">{{ $t('dialog.change_labels') }}</v-list-subheader>
|
||||
<v-list-item v-for="item in types" class="text-dark" :title="$t('dialog.change_to') + ' ' + item.label" @click="changeLabel(item)">
|
||||
<v-list-item v-for="item in types" class="text-dark" :title="$t('dialog.change_to') + ' ' + item.label"
|
||||
@click="changeLabel(item)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="green-darken-4" icon="mdi-label"></v-icon>
|
||||
</template>
|
||||
|
@ -72,7 +68,8 @@
|
|||
<v-tab value="pending">فاکتورهای در انتظار تایید</v-tab>
|
||||
</v-tabs>
|
||||
</div>
|
||||
<v-text-field hide-details color="green" class="pt-0 rounded-0 mb-0" density="compact" :placeholder="$t('dialog.search_txt')" v-model="searchValue" type="text" clearable>
|
||||
<v-text-field hide-details color="green" class="pt-0 rounded-0 mb-0" density="compact"
|
||||
:placeholder="$t('dialog.search_txt')" v-model="searchValue" type="text" clearable>
|
||||
<template v-slot:prepend-inner>
|
||||
<v-tooltip location="bottom" :text="$t('dialog.search')">
|
||||
<template v-slot:activator="{ props }">
|
||||
|
@ -102,33 +99,23 @@
|
|||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-select class="py-2 my-2" v-model="dateFilter" :items="dateFilterOptions" label="فیلتر تاریخ" @update:model-value="filterTable" dense />
|
||||
<v-select class="py-2 my-2" v-model="dateFilter" :items="dateFilterOptions" label="فیلتر تاریخ"
|
||||
@update:model-value="filterTable" dense />
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</template>
|
||||
</v-text-field>
|
||||
<v-data-table-server
|
||||
v-model:items-per-page="serverOptions.rowsPerPage"
|
||||
v-model:page="serverOptions.page"
|
||||
:headers="visibleHeaders"
|
||||
:items="displayItems"
|
||||
:items-length="displayTotal"
|
||||
:loading="loading"
|
||||
:no-data-text="$t('table.no_data')"
|
||||
v-model="itemsSelected"
|
||||
v-model:expanded="expanded"
|
||||
@update:options="updateServerOptions"
|
||||
show-select
|
||||
class="elevation-1 data-table-wrapper"
|
||||
item-value="code"
|
||||
:max-height="tableHeight"
|
||||
:header-props="{ class: 'custom-header' }"
|
||||
@update:expanded="onExpandedUpdate"
|
||||
multi-sort
|
||||
>
|
||||
<v-data-table-server v-model:items-per-page="serverOptions.rowsPerPage" v-model:page="serverOptions.page"
|
||||
:headers="visibleHeaders" :items="displayItems" :items-length="displayTotal" :loading="loading"
|
||||
:no-data-text="$t('table.no_data')" v-model="itemsSelected" v-model:expanded="expanded"
|
||||
@update:options="updateServerOptions" show-select class="elevation-1 data-table-wrapper" item-value="code"
|
||||
:max-height="tableHeight" :header-props="{ class: 'custom-header' }" @update:expanded="onExpandedUpdate"
|
||||
multi-sort>
|
||||
<template v-slot:item.expand="{ item }">
|
||||
<v-btn variant="text" size="small" color="primary" :icon="expanded.includes(item.code) ? 'mdi-chevron-up' : 'mdi-chevron-down'" @click.stop="toggleExpand(item.code)" />
|
||||
<v-btn variant="text" size="small" color="primary"
|
||||
:icon="expanded.includes(item.code) ? 'mdi-chevron-up' : 'mdi-chevron-down'"
|
||||
@click.stop="toggleExpand(item.code)" />
|
||||
</template>
|
||||
<template v-slot:item.receivedAmount="{ item }">
|
||||
<span class="text-dark">
|
||||
|
@ -141,7 +128,8 @@
|
|||
<v-btn variant="text" size="small" color="error" icon="mdi-menu" v-bind="props" />
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item class="text-dark" :title="$t('dialog.accounting_doc')" :to="'/acc/accounting/view/' + item.code">
|
||||
<v-list-item class="text-dark" :title="$t('dialog.accounting_doc')"
|
||||
:to="'/acc/accounting/view/' + item.code">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="green-darken-4" icon="mdi-file"></v-icon>
|
||||
</template>
|
||||
|
@ -151,17 +139,20 @@
|
|||
<v-icon color="green-darken-4" icon="mdi-eye"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item class="text-dark" :title="$t('dialog.export_pdf')" @click="printOptions.selectedPrintCode = item.code; modal = true;">
|
||||
<v-list-item class="text-dark" :title="$t('dialog.export_pdf')"
|
||||
@click="printOptions.selectedPrintCode = item.code; modal = true;">
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-file-pdf-box"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="isPluginActive('taxsettings')" class="text-dark" :title="$t('dialog.send_to_tax_system')" @click="sendToTaxSystem(item.code)">
|
||||
<v-list-item v-if="isPluginActive('taxsettings') && (item.isApproved || !item.isPreview)" class="text-dark"
|
||||
:title="$t('dialog.send_to_tax_system')" @click="sendToTaxSystem(item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="orange" icon="mdi-cloud-upload"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="canShowApprovalButton(item)" class="text-dark" title="تایید فاکتور" @click="approveInvoice(item.code)">
|
||||
<v-list-item v-if="canShowApprovalButton(item)" class="text-dark" title="تایید فاکتور"
|
||||
@click="approveInvoice(item.code)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="success">mdi-check-decagram</v-icon>
|
||||
</template>
|
||||
|
@ -240,7 +231,8 @@
|
|||
<template v-slot:expanded-row="{ item }">
|
||||
<tr>
|
||||
<td :colspan="visibleHeaders.length" class="expanded-row">
|
||||
<v-progress-circular v-if="loading && expanded.includes(item.code)" indeterminate color="primary" class="my-2" />
|
||||
<v-progress-circular v-if="loading && expanded.includes(item.code)" indeterminate color="primary"
|
||||
class="my-2" />
|
||||
<v-list v-else dense class="expanded-list">
|
||||
<v-list-item v-for="row in item.rows" :key="row.id">
|
||||
<v-list-item-subtitle>
|
||||
|
@ -270,7 +262,8 @@
|
|||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label">جمع سود موارد انتخاب شده:</span>
|
||||
<span class="summary-value" :class="{'text-success': sumSelectedProfit >= 0, 'text-danger': sumSelectedProfit < 0}">
|
||||
<span class="summary-value"
|
||||
:class="{ 'text-success': sumSelectedProfit >= 0, 'text-danger': sumSelectedProfit < 0 }">
|
||||
{{ $filters.formatNumber(Math.abs(sumSelectedProfit)) }}
|
||||
<span v-if="sumSelectedProfit < 0">(زیان)</span>
|
||||
</span>
|
||||
|
@ -289,7 +282,8 @@
|
|||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col v-for="header in allHeaders" :key="header.value" cols="12" sm="4" class="my-0 py-0">
|
||||
<v-checkbox v-model="header.visible" :label="header.title" @update:model-value="updateColumnVisibility" hide-details="auto" />
|
||||
<v-checkbox v-model="header.visible" :label="header.title" @update:model-value="updateColumnVisibility"
|
||||
hide-details="auto" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
|
@ -322,39 +316,46 @@
|
|||
<v-col cols="12" sm="6">
|
||||
<v-tooltip :text="$t('dialog.bid_info_label')" location="right">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-switch v-bind="props" inset v-model="printOptions.bidInfo" color="primary" :label="$t('dialog.bid_info_label')" hide-details></v-switch>
|
||||
<v-switch v-bind="props" inset v-model="printOptions.bidInfo" color="primary"
|
||||
:label="$t('dialog.bid_info_label')" hide-details></v-switch>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip :text="$t('dialog.invoice_pays')" location="right">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-switch v-bind="props" inset v-model="printOptions.pays" color="primary" :label="$t('dialog.invoice_pays')" hide-details></v-switch>
|
||||
<v-switch v-bind="props" inset v-model="printOptions.pays" color="primary"
|
||||
:label="$t('dialog.invoice_pays')" hide-details></v-switch>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip :text="$t('dialog.invoice_footer_note')" location="right">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-switch v-bind="props" inset v-model="printOptions.note" color="primary" :label="$t('dialog.invoice_footer_note')" hide-details></v-switch>
|
||||
<v-switch v-bind="props" inset v-model="printOptions.note" color="primary"
|
||||
:label="$t('dialog.invoice_footer_note')" hide-details></v-switch>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6">
|
||||
<v-tooltip :text="$t('dialog.tax_dexpo')" location="right">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-switch v-bind="props" inset v-model="printOptions.taxInfo" color="primary" :label="$t('dialog.tax_dexpo')" hide-details></v-switch>
|
||||
<v-switch v-bind="props" inset v-model="printOptions.taxInfo" color="primary"
|
||||
:label="$t('dialog.tax_dexpo')" hide-details></v-switch>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip :text="$t('dialog.discount_dexpo')" location="right">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-switch v-bind="props" inset v-model="printOptions.discountInfo" color="primary" :label="$t('dialog.discount_dexpo')" hide-details></v-switch>
|
||||
<v-switch v-bind="props" inset v-model="printOptions.discountInfo" color="primary"
|
||||
:label="$t('dialog.discount_dexpo')" hide-details></v-switch>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip :text="$t('dialog.business_stamp')" location="right">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-switch v-if="isPluginActive('accpro')" v-bind="props" inset v-model="printOptions.businessStamp" color="primary" :label="$t('dialog.business_stamp')" hide-details></v-switch>
|
||||
<v-switch v-if="isPluginActive('accpro')" v-bind="props" inset v-model="printOptions.businessStamp"
|
||||
color="primary" :label="$t('dialog.business_stamp')" hide-details></v-switch>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip :text="$t('dialog.invoice_index')" location="right">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-switch v-if="isPluginActive('accpro')" v-bind="props" inset v-model="printOptions.invoiceIndex" color="primary" :label="$t('dialog.invoice_index')" hide-details></v-switch>
|
||||
<v-switch v-if="isPluginActive('accpro')" v-bind="props" inset v-model="printOptions.invoiceIndex"
|
||||
color="primary" :label="$t('dialog.invoice_index')" hide-details></v-switch>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</v-col>
|
||||
|
@ -593,7 +594,7 @@ export default defineComponent({
|
|||
this.items = all;
|
||||
this.total = Number(response.data.total) || 0;
|
||||
if (this.business.requireTwoStepApproval) {
|
||||
this.itemsApproved = all.filter(i => i.isApproved === true);
|
||||
this.itemsApproved = all.filter(i => i.isApproved === true || (!i.isPreview && !i.isApproved));
|
||||
this.itemsPending = all.filter(i => i.isPreview === true && i.isApproved !== true);
|
||||
this.totalApproved = this.itemsApproved.length;
|
||||
this.totalPending = this.itemsPending.length;
|
||||
|
@ -752,21 +753,37 @@ export default defineComponent({
|
|||
}
|
||||
} 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 {
|
||||
this.loading = false;
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.loading = false;
|
||||
if (error?.response?.data?.message) {
|
||||
Swal.fire({
|
||||
text: error?.response?.data?.message,
|
||||
icon: 'warning',
|
||||
confirmButtonText: 'قبول'
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: 'خطا در ایجاد نسخه PDF',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'قبول'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteItem(code) {
|
||||
|
@ -933,6 +950,17 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
const selectedInvoices = this.items.filter(inv => this.itemsSelected.includes(inv.code));
|
||||
|
||||
if (selectedInvoices.some(inv => !inv.isApproved && inv.isPreview)) {
|
||||
Swal.fire({
|
||||
text: 'بعضی از فاکتورهای انتخابی هنوز تایید نشدهاند و قابل ارسال به سامانه مودیان نیستند.',
|
||||
icon: 'warning',
|
||||
confirmButtonText: 'قبول'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = this.itemsSelected.length;
|
||||
|
||||
const result = await Swal.fire({
|
||||
|
|
|
@ -24,7 +24,10 @@
|
|||
<v-tab value="2">
|
||||
{{ $t('dialog.global_settings') }}
|
||||
</v-tab>
|
||||
<v-tab value="3" v-if="showBackupTab">
|
||||
<v-tab value="3" v-if="isPluginActive('warranty')">
|
||||
{{ $t('dialog.warranty_settings') }}
|
||||
</v-tab>
|
||||
<v-tab value="4" v-if="showBackupTab">
|
||||
نسخه پشتیبان
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
@ -195,6 +198,63 @@
|
|||
</v-card-text>
|
||||
</v-card>
|
||||
</v-tabs-window-item>
|
||||
<v-tabs-window-item value="3" v-if="isPluginActive('warranty')">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<h3 class="text-primary mb-6">تنظیمات گارانتی</h3>
|
||||
<v-row>
|
||||
<v-col cols="12" md="8">
|
||||
<v-card variant="outlined" class="mb-6">
|
||||
<v-card-title class="text-h6 text-primary">
|
||||
<v-icon icon="mdi-shield-lock-outline" class="mr-2"></v-icon>
|
||||
رفتار گارانتی در حواله خروج
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-switch
|
||||
v-model="content.requireWarrantyOnDelivery"
|
||||
label="الزام ثبت گارانتی هنگام صدور حواله خروج"
|
||||
color="primary"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
/>
|
||||
<v-switch
|
||||
v-model="content.matchWarrantyToSerial"
|
||||
label="تطبیق خودکار گارانتی با سریال کالا (در صورت یکسان بودن کد)"
|
||||
color="primary"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model.number="content.activationGraceDays"
|
||||
type="number"
|
||||
min="0"
|
||||
label="مهلت فعالسازی گارانتی (روز)"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
hide-details
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4">
|
||||
<v-card variant="outlined">
|
||||
<v-card-title class="text-h6 text-primary">
|
||||
<v-icon icon="mdi-information-outline" class="mr-2"></v-icon>
|
||||
نکات
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-list density="compact">
|
||||
<v-list-item title="این تنظیمات برای همین کسبوکار ذخیره میشود." />
|
||||
<v-list-item title="در صورت فعال بودن الزام، ثبت حواله بدون سریال مجاز نیست." />
|
||||
<v-list-item title="مهلت فعالسازی فقط برای مسیر فعالسازی مشتری استفاده میشود." />
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-tabs-window-item>
|
||||
<v-tabs-window-item value="1">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
|
@ -534,7 +594,7 @@
|
|||
</v-card-text>
|
||||
</v-card>
|
||||
</v-tabs-window-item>
|
||||
<v-tabs-window-item value="3" v-if="showBackupTab">
|
||||
<v-tabs-window-item value="4" v-if="showBackupTab">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<h3 class="text-primary mb-4">نسخه پشتیبان از اطلاعات کسب و کار</h3>
|
||||
|
@ -693,7 +753,10 @@ export default {
|
|||
},
|
||||
updateSellPrice: false,
|
||||
updateBuyPrice: false,
|
||||
profitCalcType: 'lis'
|
||||
profitCalcType: 'lis',
|
||||
warrantyRequireOnDelivery: false,
|
||||
warrantyActivationGraceDays: 7,
|
||||
warrantyMatchToSerial: false
|
||||
},
|
||||
users: [],
|
||||
listBanks: [],
|
||||
|
@ -814,7 +877,10 @@ export default {
|
|||
'year': this.content.year,
|
||||
'commodityUpdateBuyPriceAuto': this.content.updateBuyPrice,
|
||||
'commodityUpdateSellPriceAuto': this.content.updateSellPrice,
|
||||
'profitCalcType': this.content.profitCalcType
|
||||
'profitCalcType': this.content.profitCalcType,
|
||||
'requireWarrantyOnDelivery': this.content.requireWarrantyOnDelivery,
|
||||
'activationGraceDays': this.content.activationGraceDays,
|
||||
'matchWarrantyToSerial': this.content.matchWarrantyToSerial
|
||||
};
|
||||
|
||||
axios.post('/api/business/insert', data)
|
||||
|
|
|
@ -3,6 +3,7 @@ import { ref, onMounted, computed } from 'vue'
|
|||
import axios from 'axios'
|
||||
import { useRouter } from 'vue-router'
|
||||
import moment from 'jalali-moment'
|
||||
import Swal from 'sweetalert2'
|
||||
|
||||
interface Business {
|
||||
legal_name: string
|
||||
|
@ -136,6 +137,13 @@ const printInvoice = async () => {
|
|||
})
|
||||
window.open(`${import.meta.env.VITE_API_URL}/front/print/${response.data.id}`, '_blank', 'noreferrer')
|
||||
} catch (error) {
|
||||
if (error?.response?.data?.message) {
|
||||
Swal.fire({
|
||||
text: error?.response?.data?.message,
|
||||
icon: 'warning',
|
||||
confirmButtonText: 'قبول'
|
||||
});
|
||||
}
|
||||
console.error('Error printing invoice:', error)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue