forked from morrning/hesabixCore
update for Moadian plugin
This commit is contained in:
parent
e2e1418137
commit
62375ab997
|
@ -19,7 +19,12 @@ use DateInterval;
|
|||
|
||||
class TaxSettingsController extends AbstractController
|
||||
{
|
||||
private $moadian_base_url = 'https://sandboxrc.tax.gov.ir/';
|
||||
|
||||
private function getMoadianBaseUrl(registryMGR $registryMGR): string
|
||||
{
|
||||
$sandboxMode = filter_var($registryMGR->get('system_settings', 'tax_system_sandbox_mode'), FILTER_VALIDATE_BOOLEAN);
|
||||
return $sandboxMode ? 'https://sandboxrc.tax.gov.ir/' : 'https://rc.tax.gov.ir/';
|
||||
}
|
||||
|
||||
#[Route('/api/plugins/tax/settings/get', name: 'plugin_tax_settings_get', methods: ['GET'])]
|
||||
public function plugin_tax_settings_get(EntityManagerInterface $em, Access $access): JsonResponse
|
||||
|
@ -216,8 +221,8 @@ class TaxSettingsController extends AbstractController
|
|||
return $csr;
|
||||
}
|
||||
|
||||
#[Route('/api/plugins/tax/settings/send-invoice', name: 'plugin_tax_settings_send_invoice', methods: ['POST'])]
|
||||
public function plugin_tax_settings_send_invoice(Request $request, Access $access, Log $log, EntityManagerInterface $em): JsonResponse
|
||||
#[Route('/api/plugins/tax/list/send-invoice', name: 'plugin_tax_list_send_invoice', methods: ['POST'])]
|
||||
public function plugin_tax_list_send_invoice(Request $request, Access $access, Log $log, EntityManagerInterface $em): JsonResponse
|
||||
{
|
||||
$acc = $access->hasRole('plugTaxSettings');
|
||||
if (!$acc) {
|
||||
|
@ -225,9 +230,9 @@ class TaxSettingsController extends AbstractController
|
|||
}
|
||||
|
||||
$params = $request->getPayload()->all();
|
||||
$invoiceCode = $params['code'] ?? null;
|
||||
$invoiceCodes = $params['codes'] ?? [];
|
||||
|
||||
if (!$invoiceCode) {
|
||||
if (empty($invoiceCodes)) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'کد فاکتور الزامی است'
|
||||
|
@ -239,20 +244,6 @@ class TaxSettingsController extends AbstractController
|
|||
$userId = $user instanceof \App\Entity\User ? $user->getId() : null;
|
||||
|
||||
try {
|
||||
$invoiceRepo = $em->getRepository(HesabdariDoc::class);
|
||||
$invoice = $invoiceRepo->findOneBy([
|
||||
'code' => $invoiceCode,
|
||||
'bid' => $businessId,
|
||||
'type' => 'sell'
|
||||
]);
|
||||
|
||||
if (!$invoice) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'فاکتور مورد نظر یافت نشد'
|
||||
]);
|
||||
}
|
||||
|
||||
$taxRepo = $em->getRepository(PluginTaxsettingsKey::class);
|
||||
$taxSettings = $taxRepo->findOneBy([
|
||||
'business_id' => $businessId,
|
||||
|
@ -266,28 +257,89 @@ class TaxSettingsController extends AbstractController
|
|||
]);
|
||||
}
|
||||
|
||||
$invoiceRepo = $em->getRepository(HesabdariDoc::class);
|
||||
$results = [];
|
||||
$successCount = 0;
|
||||
$errorCount = 0;
|
||||
$processedCodes = [];
|
||||
|
||||
foreach ($invoiceCodes as $invoiceCode) {
|
||||
$invoiceCode = trim($invoiceCode);
|
||||
if (empty($invoiceCode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$invoice = $invoiceRepo->findOneBy([
|
||||
'code' => $invoiceCode,
|
||||
'bid' => $businessId,
|
||||
'type' => 'sell'
|
||||
]);
|
||||
|
||||
if (!$invoice) {
|
||||
$results[] = [
|
||||
'code' => $invoiceCode,
|
||||
'success' => false,
|
||||
'message' => 'فاکتور مورد نظر یافت نشد'
|
||||
];
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = $this->saveInvoiceToSql($invoice, $taxSettings, $em, $businessId, $userId);
|
||||
|
||||
if ($result['success']) {
|
||||
$log->insert('اضافه به لیست ارسال', 'فاکتور ' . $invoiceCode . ' به لیست ارسال به سامانه مودیان اضافه شد', $this->getUser(), $businessId);
|
||||
|
||||
return $this->json([
|
||||
$results[] = [
|
||||
'code' => $invoiceCode,
|
||||
'success' => true,
|
||||
'message' => 'فاکتور با موفقیت به لیست ارسال اضافه شد',
|
||||
'data' => $result['data'] ?? null
|
||||
]);
|
||||
];
|
||||
$successCount++;
|
||||
$processedCodes[] = $invoiceCode;
|
||||
} else {
|
||||
return $this->json([
|
||||
$results[] = [
|
||||
'code' => $invoiceCode,
|
||||
'success' => false,
|
||||
'message' => $result['message'] ?? 'خطا در اضافه کردن به لیست ارسال'
|
||||
]);
|
||||
];
|
||||
$errorCount++;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$log->insert('خطا در اضافه به لیست ارسال', 'خطا در اضافه کردن فاکتور ' . $invoiceCode . ' به لیست ارسال: ' . $e->getMessage(), $this->getUser(), $businessId);
|
||||
$results[] = [
|
||||
'code' => $invoiceCode,
|
||||
'success' => false,
|
||||
'message' => 'خطا در پردازش فاکتور: ' . $e->getMessage()
|
||||
];
|
||||
$errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($processedCodes)) {
|
||||
$codesText = implode(', ', $processedCodes);
|
||||
$log->insert('اضافه به لیست ارسال', 'فاکتورهای ' . $codesText . ' به لیست ارسال به سامانه مودیان اضافه شد', $this->getUser(), $businessId);
|
||||
}
|
||||
|
||||
$totalProcessed = count($invoiceCodes);
|
||||
$message = "پردازش {$totalProcessed} فاکتور تکمیل شد. موفق: {$successCount}, ناموفق: {$errorCount}";
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'message' => $message,
|
||||
'summary' => [
|
||||
'total' => $totalProcessed,
|
||||
'success' => $successCount,
|
||||
'error' => $errorCount
|
||||
],
|
||||
'results' => $results
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$log->insert('خطا در اضافه به لیست ارسال', 'خطا در پردازش فاکتورها: ' . $e->getMessage(), $this->getUser(), $businessId);
|
||||
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'خطا در اضافه کردن به لیست ارسال: ' . $e->getMessage()
|
||||
'message' => 'خطا در پردازش فاکتورها: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -663,7 +715,7 @@ class TaxSettingsController extends AbstractController
|
|||
}
|
||||
|
||||
#[Route('/api/plugins/tax/invoice/send/{id}', name: 'plugin_tax_invoice_send', methods: ['POST'])]
|
||||
public function sendTaxInvoice(int $id, Access $access, Log $log, EntityManagerInterface $em): JsonResponse
|
||||
public function sendTaxInvoice(int $id, Access $access, Log $log, EntityManagerInterface $em, registryMGR $registryMGR): JsonResponse
|
||||
{
|
||||
$acc = $access->hasRole('plugTaxSettings');
|
||||
if (!$acc) {
|
||||
|
@ -722,7 +774,7 @@ class TaxSettingsController extends AbstractController
|
|||
$privateKey,
|
||||
'',
|
||||
$username,
|
||||
$this->moadian_base_url
|
||||
$this->getMoadianBaseUrl($registryMGR)
|
||||
);
|
||||
|
||||
$serverInfo = $moadian->getServerInformation();
|
||||
|
@ -741,7 +793,7 @@ class TaxSettingsController extends AbstractController
|
|||
$privateKey,
|
||||
$taxOrgKeyId,
|
||||
$username,
|
||||
$this->moadian_base_url
|
||||
$this->getMoadianBaseUrl($registryMGR)
|
||||
);
|
||||
|
||||
$token = $moadian->login();
|
||||
|
@ -880,7 +932,7 @@ class TaxSettingsController extends AbstractController
|
|||
}
|
||||
|
||||
#[Route('/api/plugins/tax/inquire-status', name: 'plugin_tax_inquire_status', methods: ['POST'])]
|
||||
public function inquireInvoiceStatus(Request $request, Access $access, EntityManagerInterface $em): JsonResponse
|
||||
public function inquireInvoiceStatus(Request $request, Access $access, EntityManagerInterface $em, registryMGR $registryMGR): JsonResponse
|
||||
{
|
||||
$acc = $access->hasRole('plugTaxSettings');
|
||||
if (!$acc) {
|
||||
|
@ -922,7 +974,7 @@ class TaxSettingsController extends AbstractController
|
|||
$privateKey,
|
||||
$taxOrgKeyId,
|
||||
$username,
|
||||
$this->moadian_base_url
|
||||
$this->getMoadianBaseUrl($registryMGR)
|
||||
);
|
||||
|
||||
$token = $moadian->login();
|
||||
|
@ -1180,6 +1232,238 @@ class TaxSettingsController extends AbstractController
|
|||
}
|
||||
}
|
||||
|
||||
#[Route('/api/plugins/tax/invoice/send-bulk', name: 'plugin_tax_invoice_send_bulk', methods: ['POST'])]
|
||||
public function sendBulkTaxInvoices(Request $request, Access $access, Log $log, EntityManagerInterface $em, registryMGR $registryMGR): JsonResponse
|
||||
{
|
||||
$acc = $access->hasRole('plugTaxSettings');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException('شما دسترسی لازم را ندارید.');
|
||||
}
|
||||
|
||||
$params = $request->getPayload()->all();
|
||||
$invoiceIds = $params['ids'] ?? [];
|
||||
|
||||
if (empty($invoiceIds)) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'شناسه فاکتورهای مالیاتی الزامی است'
|
||||
]);
|
||||
}
|
||||
|
||||
$businessId = is_object($acc['bid']) ? $acc['bid']->getId() : $acc['bid'];
|
||||
$user = $this->getUser();
|
||||
$userId = $user instanceof \App\Entity\User ? $user->getId() : null;
|
||||
|
||||
$repo = $em->getRepository(PluginTaxsettingsKey::class);
|
||||
$taxSettings = $repo->findOneBy(['business_id' => $businessId, 'user_id' => $userId]);
|
||||
|
||||
if (!$taxSettings || !$taxSettings->getPrivateKey() || !$taxSettings->getTaxMemoryId()) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'تنظیمات مالیاتی تکمیل نشده است. لطفاً ابتدا تنظیمات را تکمیل کنید.'
|
||||
]);
|
||||
}
|
||||
|
||||
try {
|
||||
$username = $taxSettings->getTaxMemoryId();
|
||||
$privateKey = $taxSettings->getPrivateKey();
|
||||
|
||||
if (!$username || !$privateKey) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'تنظیمات مالیاتی تکمیل نشده است. لطفاً ابتدا تنظیمات را تکمیل کنید.'
|
||||
]);
|
||||
}
|
||||
|
||||
$moadian = new \SnappMarketPro\Moadian\Moadian(
|
||||
'',
|
||||
$privateKey,
|
||||
'',
|
||||
$username,
|
||||
$this->getMoadianBaseUrl($registryMGR)
|
||||
);
|
||||
|
||||
$serverInfo = $moadian->getServerInformation();
|
||||
if (!isset($serverInfo['result']['data']['publicKeys'][0])) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'خطا در دریافت اطلاعات سرور مودیان'
|
||||
]);
|
||||
}
|
||||
|
||||
$taxOrgPublicKey = $serverInfo['result']['data']['publicKeys'][0]['key'];
|
||||
$taxOrgKeyId = $serverInfo['result']['data']['publicKeys'][0]['id'];
|
||||
|
||||
$moadian = new \SnappMarketPro\Moadian\Moadian(
|
||||
$taxOrgPublicKey,
|
||||
$privateKey,
|
||||
$taxOrgKeyId,
|
||||
$username,
|
||||
$this->getMoadianBaseUrl($registryMGR)
|
||||
);
|
||||
|
||||
$token = $moadian->login();
|
||||
|
||||
if (!$token) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'خطا در اتصال به سامانه مودیان، لطفاً تنظیمات را بررسی کنید.'
|
||||
]);
|
||||
}
|
||||
|
||||
$moadian->setToken($token);
|
||||
|
||||
$taxInvoiceRepo = $em->getRepository(PluginTaxInvoice::class);
|
||||
$results = [];
|
||||
$successCount = 0;
|
||||
$errorCount = 0;
|
||||
$processedCodes = [];
|
||||
|
||||
foreach ($invoiceIds as $id) {
|
||||
try {
|
||||
$taxInvoice = $taxInvoiceRepo->findOneBy([
|
||||
'id' => $id,
|
||||
'business' => $businessId
|
||||
]);
|
||||
|
||||
if (!$taxInvoice) {
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => null,
|
||||
'success' => false,
|
||||
'message' => 'فاکتور مالیاتی مورد نظر یافت نشد'
|
||||
];
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$invoiceStatus = $taxInvoice->getStatus();
|
||||
|
||||
if ($invoiceStatus !== 'pending' && $invoiceStatus !== 'error') {
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => $taxInvoice->getInvoiceCode(),
|
||||
'success' => false,
|
||||
'message' => 'فقط فاکتورهای ارسال نشده یا خطا دار قابل ارسال هستند'
|
||||
];
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$invoice = $taxInvoice->getInvoice();
|
||||
|
||||
if (!$invoice) {
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => $taxInvoice->getInvoiceCode(),
|
||||
'success' => false,
|
||||
'message' => 'فاکتور معتبر نیست'
|
||||
];
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$validationResult = $this->validateInvoiceForTax($invoice);
|
||||
if (!$validationResult['valid']) {
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => $taxInvoice->getInvoiceCode(),
|
||||
'success' => false,
|
||||
'message' => $validationResult['message']
|
||||
];
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$invoiceDto = $this->buildInvoiceDto($invoice, $moadian, $taxSettings->getEconomicCode());
|
||||
if (!$invoiceDto) {
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => $taxInvoice->getInvoiceCode(),
|
||||
'success' => false,
|
||||
'message' => 'خطا در آمادهسازی فاکتور: خطا در ساخت DTO فاکتور'
|
||||
];
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$response = $moadian->sendInvoices([$invoiceDto]);
|
||||
|
||||
if (isset($response['result'][0]['referenceNumber']) && !empty($response['result'])) {
|
||||
$taxInvoice->setStatus('sent');
|
||||
$taxInvoice->setTaxSystemInvoiceNumber($response['result'][0]['referenceNumber']);
|
||||
$taxInvoice->setSentAt(new \DateTimeImmutable());
|
||||
$em->persist($taxInvoice);
|
||||
$em->flush();
|
||||
|
||||
if ($invoiceStatus === 'error') {
|
||||
$taxInvoice->setInvoiceType('اصلاحی');
|
||||
$em->persist($taxInvoice);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => $taxInvoice->getInvoiceCode(),
|
||||
'success' => true,
|
||||
'message' => 'فاکتور با موفقیت ارسال شد',
|
||||
'referenceNumber' => $response['result'][0]['referenceNumber'] ?? null
|
||||
];
|
||||
$successCount++;
|
||||
$processedCodes[] = $taxInvoice->getInvoiceCode();
|
||||
} else {
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => $taxInvoice->getInvoiceCode(),
|
||||
'success' => false,
|
||||
'message' => 'خطا در ارسال فاکتور: ' . ($response['result'][0]['error'] ?? 'خطای نامشخص')
|
||||
];
|
||||
$errorCount++;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$results[] = [
|
||||
'id' => $id,
|
||||
'code' => $taxInvoice->getInvoiceCode() ?? null,
|
||||
'success' => false,
|
||||
'message' => 'خطا در پردازش فاکتور: ' . $e->getMessage()
|
||||
];
|
||||
$errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($processedCodes)) {
|
||||
$codesText = implode(', ', $processedCodes);
|
||||
$log->insert(
|
||||
'ارسال گروهی فاکتورهای مالیاتی',
|
||||
'فاکتورهای مالیاتی ' . $codesText . ' به سامانه مودیان ارسال شد.',
|
||||
$this->getUser(),
|
||||
$businessId
|
||||
);
|
||||
}
|
||||
|
||||
$totalProcessed = count($invoiceIds);
|
||||
$message = "پردازش {$totalProcessed} فاکتور مالیاتی تکمیل شد. موفق: {$successCount}, ناموفق: {$errorCount}";
|
||||
|
||||
return $this->json([
|
||||
'success' => $successCount > 0,
|
||||
'message' => $message,
|
||||
'summary' => [
|
||||
'total' => $totalProcessed,
|
||||
'success' => $successCount,
|
||||
'error' => $errorCount
|
||||
],
|
||||
'results' => $results
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'message' => 'خطا در ارسال گروهی فاکتورهای مالیاتی: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ final class RegistrySettingsController extends AbstractController
|
|||
'appUrl' => $registryMGR->get('system', 'appUrl'),
|
||||
'appSlogan' => $registryMGR->get('system', 'appSlogan'),
|
||||
'verifyMobileViaSms' => filter_var($registryMGR->get('system', 'verifyMobileViaSms'), FILTER_VALIDATE_BOOLEAN),
|
||||
'taxSystemSandboxMode' => filter_var($registryMGR->get($rootSystem, 'tax_system_sandbox_mode'), FILTER_VALIDATE_BOOLEAN),
|
||||
// تنظیمات FTP
|
||||
'ftpEnabled' => filter_var($registryMGR->get($rootSystem, 'ftp_enabled'), FILTER_VALIDATE_BOOLEAN),
|
||||
'ftpHost' => $registryMGR->get($rootSystem, 'ftp_host') ?: '',
|
||||
|
@ -96,6 +97,7 @@ final class RegistrySettingsController extends AbstractController
|
|||
$registryMGR->update('system', 'appUrl', $data['appUrl'] ?? '');
|
||||
$registryMGR->update('system', 'appSlogan', $data['appSlogan'] ?? '');
|
||||
$registryMGR->update('system', 'verifyMobileViaSms', $data['verifyMobileViaSms'] ? '1' : '0');
|
||||
$registryMGR->update($rootSystem, 'tax_system_sandbox_mode', $data['taxSystemSandboxMode'] ? '1' : '0');
|
||||
// ذخیره تنظیمات FTP
|
||||
$registryMGR->update($rootSystem, 'ftp_enabled', $data['ftpEnabled'] ? '1' : '0');
|
||||
$registryMGR->update($rootSystem, 'ftp_host', $data['ftpHost'] ?? '');
|
||||
|
|
|
@ -571,7 +571,7 @@ const fa_lang = {
|
|||
status: "وضعیت",
|
||||
actions: "عملیات"
|
||||
},
|
||||
send_to_tax_system: "ارسال به سامانه مودیان",
|
||||
send_to_tax_system: "ارسال به کارپوشه مودیان",
|
||||
tax_send_success: "فاکتور با موفقیت به سامانه مودیان ارسال شد.",
|
||||
tax_send_error: "ارسال به سامانه مودیان با خطا مواجه شد.",
|
||||
},
|
||||
|
|
|
@ -10,6 +10,12 @@
|
|||
</v-tooltip>
|
||||
</template>
|
||||
<v-spacer></v-spacer>
|
||||
<v-tooltip text="ارسال گروهی به سامانه مودیان مالیاتی" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" icon="mdi-cloud-upload" color="orange" @click="sendBulkInvoices()"
|
||||
:disabled="selectedInvoices.length === 0" :loading="bulkLoading" class="me-2"></v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-btn :loading="loading" @click="loadData()" icon color="primary">
|
||||
<v-tooltip activator="parent" text="بازخوانی" location="bottom" />
|
||||
<v-icon icon="mdi-refresh"></v-icon>
|
||||
|
@ -18,37 +24,31 @@
|
|||
|
||||
<v-container>
|
||||
<v-alert type="info" color="blue" class="mb-4" icon="mdi-information">
|
||||
<span class="font-weight-bold">این بخش برای نمایش لیست صورتحساب هایی است که به سامانه مودیان مالیاتی
|
||||
<span class="font-weight-bold">این بخش برای نمایش لیست صورتحساب هایی است که به سامانه مودیان
|
||||
مالیاتی
|
||||
ارسال
|
||||
شدهاند.</span>
|
||||
</v-alert>
|
||||
<v-card :loading="loading" :disabled="loading" class="elevation-1">
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="invoices"
|
||||
:loading="loading"
|
||||
class="elevation-1 data-table-wrapper"
|
||||
:items-per-page="10"
|
||||
:items-per-page-options="[10, 25, 50, 100]"
|
||||
:header-props="{ class: 'custom-header' }"
|
||||
>
|
||||
<v-data-table :headers="headers" :items="invoices" :loading="loading"
|
||||
class="elevation-1 data-table-wrapper" :items-per-page="10"
|
||||
:items-per-page-options="[10, 25, 50, 100]" :header-props="{ class: 'custom-header' }"
|
||||
v-model="selectedInvoices" show-select item-value="id" :item-selectable="isItemSelectable">
|
||||
<template v-slot:item.invoiceNumber="{ item }">
|
||||
<router-link :to="'/acc/sell/mod/' + item.invoiceNumber" class="text-decoration-none">
|
||||
<span class="text-primary font-weight-medium">{{ item.invoiceNumber }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
<template v-slot:item.customerName="{ item }">
|
||||
<router-link v-if="item.customerId" :to="'/acc/persons/card/view/' + item.customerId" class="text-decoration-none">
|
||||
<router-link v-if="item.customerId" :to="'/acc/persons/card/view/' + item.customerId"
|
||||
class="text-decoration-none">
|
||||
<span class="text-primary font-weight-medium">{{ item.customerName || '-' }}</span>
|
||||
</router-link>
|
||||
<span v-else class="text-muted">{{ item.customerName || '-' }}</span>
|
||||
</template>
|
||||
<template v-slot:item.invoiceType="{ item }">
|
||||
<v-chip
|
||||
:color="getInvoiceTypeColor(item.invoiceType)"
|
||||
size="small"
|
||||
class="font-weight-medium"
|
||||
>
|
||||
<v-chip :color="getInvoiceTypeColor(item.invoiceType)" size="small"
|
||||
class="font-weight-medium">
|
||||
{{ item.invoiceType }}
|
||||
</v-chip>
|
||||
</template>
|
||||
|
@ -75,68 +75,51 @@
|
|||
<template v-slot:item.actions="{ item }">
|
||||
<v-menu>
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn variant="text" size="small" color="error" icon="mdi-menu" v-bind="props" />
|
||||
<v-btn variant="text" size="small" color="error" icon="mdi-menu"
|
||||
v-bind="props" />
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item
|
||||
v-if="item.status === 'pending'"
|
||||
class="text-green-darken-4"
|
||||
:title="'ارسال به سامانه'"
|
||||
@click="sendInvoice(item)"
|
||||
:loading="item.sending"
|
||||
>
|
||||
<v-list-item v-if="item.status === 'pending'" class="text-green-darken-4"
|
||||
:title="'ارسال به سامانه'" @click="sendInvoice(item)"
|
||||
:loading="item.sending">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="green-darken-4" icon="mdi-cloud-upload"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
v-if="item.status === 'error'"
|
||||
class="text-green-darken-4"
|
||||
:title="'ارسال مجدد به سامانه'"
|
||||
@click="sendInvoice(item)"
|
||||
:loading="item.sending"
|
||||
>
|
||||
<v-list-item v-if="item.status === 'error'" class="text-green-darken-4"
|
||||
:title="'ارسال مجدد به سامانه'" @click="sendInvoice(item)"
|
||||
:loading="item.sending">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="green-darken-4" icon="mdi-cloud-upload"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
v-if="item.status === 'error'"
|
||||
class="text-dark"
|
||||
:title="'مشاهده خطاها'"
|
||||
@click="showErrorsDialog(item)"
|
||||
>
|
||||
<v-list-item v-if="item.status === 'error'" class="text-dark"
|
||||
:title="'مشاهده خطاها'" @click="showErrorsDialog(item)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="red-darken-4" icon="mdi-alert-circle"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item class="text-dark" :title="'مشاهده فاکتور'" :to="'/acc/sell/view/' + item.invoiceNumber">
|
||||
<v-list-item class="text-dark" :title="'مشاهده فاکتور'"
|
||||
:to="'/acc/sell/view/' + item.invoiceNumber">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="green-darken-4" icon="mdi-eye"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="item.customerId" class="text-dark" :title="'مشاهده مشتری'" :to="'/acc/persons/card/view/' + item.customerId">
|
||||
<v-list-item v-if="item.customerId" class="text-dark" :title="'مشاهده مشتری'"
|
||||
:to="'/acc/persons/card/view/' + item.customerId">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="blue-darken-4" icon="mdi-account"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
v-if="item.uniqueTaxNumber && item.status === 'sent'"
|
||||
class="text-dark"
|
||||
:title="'بررسی وضعیت صورت حساب'"
|
||||
@click="checkInvoiceStatus(item)"
|
||||
:loading="item.checkingStatus"
|
||||
>
|
||||
<v-list-item v-if="item.uniqueTaxNumber && item.status === 'sent'"
|
||||
class="text-dark" :title="'بررسی وضعیت صورت حساب'"
|
||||
@click="checkInvoiceStatus(item)" :loading="item.checkingStatus">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="orange-darken-4" icon="mdi-refresh"></v-icon>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
v-if="item.status === 'pending' || item.status === 'error'"
|
||||
class="text-red-darken-4"
|
||||
:title="'حذف'"
|
||||
@click="deleteInvoice(item)"
|
||||
>
|
||||
<v-list-item v-if="item.status === 'pending' || item.status === 'error'"
|
||||
class="text-red-darken-4" :title="'حذف'" @click="deleteInvoice(item)">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="deep-orange-accent-4" icon="mdi-trash-can"></v-icon>
|
||||
</template>
|
||||
|
@ -175,18 +158,16 @@
|
|||
خطاها ({{ errorsDialog.errors.length }} مورد):
|
||||
</div>
|
||||
<v-list density="compact" class="mb-4">
|
||||
<v-list-item
|
||||
v-for="(error, index) in errorsDialog.errors"
|
||||
:key="index"
|
||||
<v-list-item v-for="(error, index) in errorsDialog.errors" :key="index"
|
||||
class="mb-3 pa-3"
|
||||
style="border: 1px solid #ffebee; border-radius: 8px; background-color: #fff5f5;"
|
||||
>
|
||||
style="border: 1px solid #ffebee; border-radius: 8px; background-color: #fff5f5;">
|
||||
<template v-slot:prepend>
|
||||
<v-icon color="red" size="small" class="mt-1">mdi-alert</v-icon>
|
||||
</template>
|
||||
<v-list-item-title class="text-body-2 font-weight-medium mb-1 error-message">
|
||||
<div v-if="error.code" class="error-code mb-2">
|
||||
<v-chip size="small" color="red" variant="outlined" class="font-weight-bold">
|
||||
<v-chip size="small" color="red" variant="outlined"
|
||||
class="font-weight-bold">
|
||||
کد خطا: {{ error.code }}
|
||||
</v-chip>
|
||||
</div>
|
||||
|
@ -241,19 +222,12 @@
|
|||
|
||||
<v-card-actions class="pa-4">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
@click="errorsDialog.show = false"
|
||||
prepend-icon="mdi-close"
|
||||
>
|
||||
<v-btn color="primary" variant="outlined" @click="errorsDialog.show = false"
|
||||
prepend-icon="mdi-close">
|
||||
بستن
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="primary"
|
||||
:to="'/acc/sell/mod/' + errorsDialog.invoiceNumber"
|
||||
prepend-icon="mdi-pencil"
|
||||
>
|
||||
<v-btn color="primary" :to="'/acc/sell/mod/' + errorsDialog.invoiceNumber"
|
||||
prepend-icon="mdi-pencil">
|
||||
ویرایش فاکتور
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
|
@ -262,14 +236,16 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import Swal from 'sweetalert2';
|
||||
export default {
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import Swal from 'sweetalert2';
|
||||
export default {
|
||||
name: 'TaxInvoicesList',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
bulkLoading: false,
|
||||
selectedInvoices: [],
|
||||
invoices: [],
|
||||
snackbar: {
|
||||
show: false,
|
||||
|
@ -290,7 +266,7 @@
|
|||
{ title: 'مبلغ کل', key: 'totalAmount', sortable: true },
|
||||
{ title: 'موضوع صورتحساب', key: 'invoiceType', sortable: true },
|
||||
{ title: 'شماره منحصر به فرد مالیاتی', key: 'uniqueTaxNumber', sortable: true },
|
||||
{ title: 'شماره منحصر به فرد مالیاتی صورتحساب مرجع', key: 'referenceUniqueTaxNumber', sortable: true },
|
||||
// { title: 'شماره منحصر به فرد مالیاتی صورتحساب مرجع', key: 'referenceUniqueTaxNumber', sortable: true },
|
||||
{ title: 'تاریخ ارسال', key: 'sentDate', sortable: true },
|
||||
{ title: 'وضعیت', key: 'status', sortable: true },
|
||||
]
|
||||
|
@ -408,8 +384,7 @@
|
|||
if (statusData && statusData.length > 0) {
|
||||
const invoiceStatus = statusData[0];
|
||||
|
||||
if ((invoiceStatus.data && invoiceStatus.data.error && invoiceStatus.data.error.length > 0) ||
|
||||
(invoiceStatus.data && invoiceStatus.data.warning && invoiceStatus.data.warning.length > 0)) {
|
||||
if ((invoiceStatus.data && invoiceStatus.data.error && invoiceStatus.data.error.length > 0)) {
|
||||
|
||||
this.errorsDialog = {
|
||||
show: true,
|
||||
|
@ -537,7 +512,7 @@
|
|||
sendInvoice(item) {
|
||||
Swal.fire({
|
||||
title: '',
|
||||
text: `آیا از ارسال فاکتور شماره ${item.invoiceNumber} به سامانه مودیان اطمینان دارید؟`,
|
||||
text: `آیا از ارسال فاکتور شماره ${item.invoiceNumber} به سامانه مودیان مالیاتی اطمینان دارید؟`,
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'بله',
|
||||
|
@ -556,7 +531,7 @@
|
|||
if (response.data.success) {
|
||||
Swal.fire({
|
||||
title: 'ارسال موفق',
|
||||
text: 'فاکتور با موفقیت به سامانه مودیان ارسال شد',
|
||||
text: 'فاکتور با موفقیت به سامانه مودیان مالیاتی ارسال شد',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'باشه'
|
||||
});
|
||||
|
@ -579,76 +554,166 @@
|
|||
} finally {
|
||||
item.sending = false;
|
||||
}
|
||||
},
|
||||
sendBulkInvoices() {
|
||||
if (this.selectedInvoices.length === 0) {
|
||||
this.showSnackbar('لطفاً حداقل یک فاکتور را انتخاب کنید', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedItems = this.invoices.filter(invoice =>
|
||||
this.selectedInvoices.includes(invoice.id)
|
||||
);
|
||||
|
||||
Swal.fire({
|
||||
title: 'ارسال گروهی فاکتورهای مالیاتی',
|
||||
text: `آیا از ارسال ${selectedItems.length} فاکتور انتخاب شده به سامانه مودیان مالیاتی اطمینان دارید؟`,
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'بله، ارسال کن',
|
||||
cancelButtonText: 'انصراف',
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
this.performBulkSend(selectedItems);
|
||||
}
|
||||
});
|
||||
},
|
||||
async performBulkSend(selectedItems) {
|
||||
this.bulkLoading = true;
|
||||
try {
|
||||
const response = await axios.post('/api/plugins/tax/invoice/send-bulk', {
|
||||
ids: selectedItems.map(item => item.id)
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
const summary = response.data.summary;
|
||||
const results = response.data.results;
|
||||
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
const errorMessages = [];
|
||||
|
||||
results.forEach(result => {
|
||||
if (result.success) {
|
||||
successCount++;
|
||||
} else {
|
||||
errorCount++;
|
||||
errorMessages.push(`${result.code}: ${result.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
let message = `پردازش ${summary.total} فاکتور مالیاتی تکمیل شد.\n\n`;
|
||||
message += `✅ موفق: ${successCount} فاکتور\n`;
|
||||
message += `❌ ناموفق: ${errorCount} فاکتور`;
|
||||
|
||||
if (errorCount > 0 && errorMessages.length > 0) {
|
||||
message += `\n\nفاکتورهای ناموفق:\n${errorMessages.slice(0, 5).join('\n')}`;
|
||||
if (errorMessages.length > 5) {
|
||||
message += `\nو ${errorMessages.length - 5} فاکتور دیگر...`;
|
||||
}
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: successCount > 0 ? 'ارسال گروهی تکمیل شد' : 'خطا در ارسال گروهی',
|
||||
html: message.replace(/\n/g, '<br>'),
|
||||
icon: successCount > 0 ? 'success' : 'error',
|
||||
confirmButtonText: 'باشه'
|
||||
});
|
||||
|
||||
this.selectedInvoices = [];
|
||||
this.loadData();
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'خطا در ارسال گروهی',
|
||||
text: response.data.message || 'خطا در ارسال گروهی فاکتورها',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'باشه'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
Swal.fire({
|
||||
title: 'خطا در ارسال گروهی',
|
||||
text: 'خطا در ارسال گروهی فاکتورها: ' + (error.response?.data?.message || error.message),
|
||||
icon: 'error',
|
||||
confirmButtonText: 'باشه'
|
||||
});
|
||||
} finally {
|
||||
this.bulkLoading = false;
|
||||
}
|
||||
},
|
||||
isItemSelectable(item) {
|
||||
return item.status === 'pending' || item.status === 'error';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadData();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.data-table-wrapper {
|
||||
<style>
|
||||
.data-table-wrapper {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-header {
|
||||
.custom-header {
|
||||
background-color: #213E8B !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text-decoration-none {
|
||||
.text-decoration-none {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
.text-primary {
|
||||
color: #1976d2 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text-success {
|
||||
.text-success {
|
||||
color: #4caf50 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
.text-info {
|
||||
color: #2196f3 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text-dark {
|
||||
.text-dark {
|
||||
color: #212121 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
.text-muted {
|
||||
color: #757575 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.font-weight-medium {
|
||||
.font-weight-medium {
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.font-weight-bold {
|
||||
.font-weight-bold {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
}
|
||||
|
||||
.error-message,
|
||||
.warning-message {
|
||||
.error-message,
|
||||
.warning-message {
|
||||
white-space: pre-wrap !important;
|
||||
word-wrap: break-word !important;
|
||||
word-break: break-word !important;
|
||||
line-height: 1.5 !important;
|
||||
max-width: 100% !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
}
|
||||
|
||||
.error-code,
|
||||
.warning-code {
|
||||
.error-code,
|
||||
.warning-code {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.error-code,
|
||||
.warning-code {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
}
|
||||
</style>
|
|
@ -19,6 +19,18 @@
|
|||
<v-btn v-bind="props" icon="mdi-delete" color="danger" @click="deleteItems()"></v-btn>
|
||||
</template>
|
||||
</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>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-menu>
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" icon="" color="green">
|
||||
|
@ -364,6 +376,7 @@ export default defineComponent({
|
|||
searchValue: '',
|
||||
types: [],
|
||||
loading: false,
|
||||
bulkLoading: false,
|
||||
items: [],
|
||||
total: 0,
|
||||
expanded: [],
|
||||
|
@ -726,8 +739,14 @@ export default defineComponent({
|
|||
async sendToTaxSystem(code) {
|
||||
this.loading = true;
|
||||
try {
|
||||
const response = await axios.post('/api/plugins/tax/settings/send-invoice', { code });
|
||||
const response = await axios.post('/api/plugins/tax/list/send-invoice', { codes: [code] });
|
||||
|
||||
if (response.data.success) {
|
||||
const results = response.data.results;
|
||||
|
||||
const invoiceResult = results.find(r => r.code === code);
|
||||
|
||||
if (invoiceResult && invoiceResult.success) {
|
||||
Swal.fire({
|
||||
text: this.$t('dialog.tax_send_success'),
|
||||
icon: 'success',
|
||||
|
@ -737,6 +756,14 @@ export default defineComponent({
|
|||
this.$router.push('/acc/plugins/tax/invoices/list');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const errorMessage = invoiceResult?.message || response.data.message || this.$t('dialog.tax_send_error');
|
||||
Swal.fire({
|
||||
text: errorMessage,
|
||||
icon: 'error',
|
||||
confirmButtonText: this.$t('dialog.ok')
|
||||
});
|
||||
}
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: response.data.message || this.$t('dialog.tax_send_error'),
|
||||
|
@ -754,6 +781,96 @@ export default defineComponent({
|
|||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async sendBulkToTaxSystem() {
|
||||
if (this.itemsSelected.length === 0) {
|
||||
Swal.fire({
|
||||
text: 'هیچ فاکتوری انتخاب نشده است.',
|
||||
icon: 'warning',
|
||||
confirmButtonText: 'قبول'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = this.itemsSelected.length;
|
||||
|
||||
const result = await Swal.fire({
|
||||
title: 'ارسال گروهی به کارپوشه مودیان',
|
||||
text: `آیا میخواهید ${selectedCount} فاکتور انتخاب شده را به کارپوشه مودیان ارسال کنید؟`,
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'بله، ارسال کن',
|
||||
cancelButtonText: 'انصراف',
|
||||
confirmButtonColor: '#ff9800',
|
||||
cancelButtonColor: '#6c757d'
|
||||
});
|
||||
|
||||
if (result.isConfirmed) {
|
||||
this.bulkLoading = true;
|
||||
try {
|
||||
const response = await axios.post('/api/plugins/tax/list/send-invoice', {
|
||||
codes: this.itemsSelected
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
const summary = response.data.summary;
|
||||
const results = response.data.results;
|
||||
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
let errorMessages = [];
|
||||
|
||||
results.forEach(result => {
|
||||
if (result.success) {
|
||||
successCount++;
|
||||
} else {
|
||||
errorCount++;
|
||||
errorMessages.push(`${result.code}: ${result.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
let message = `پردازش ${summary.total} فاکتور تکمیل شد.\n\n`;
|
||||
message += `✅ موفق: ${successCount} فاکتور\n`;
|
||||
message += `❌ ناموفق: ${errorCount} فاکتور`;
|
||||
|
||||
if (errorCount > 0 && errorMessages.length > 0) {
|
||||
message += `\n\nفاکتورهای ناموفق:\n${errorMessages.slice(0, 5).join('\n')}`;
|
||||
if (errorMessages.length > 5) {
|
||||
message += `\nو ${errorMessages.length - 5} فاکتور دیگر...`;
|
||||
}
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: 'نتیجه ارسال گروهی',
|
||||
html: message.replace(/\n/g, '<br>'),
|
||||
icon: successCount > 0 ? 'success' : 'error',
|
||||
confirmButtonText: 'قبول',
|
||||
width: '600px'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed && successCount > 0) {
|
||||
this.$router.push('/acc/plugins/tax/invoices/list');
|
||||
}
|
||||
});
|
||||
|
||||
this.itemsSelected = [];
|
||||
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: response.data.message || 'خطا در ارسال گروهی فاکتورها',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'قبول'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
Swal.fire({
|
||||
text: error.response?.data?.message || 'خطا در ارسال گروهی فاکتورها',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'قبول'
|
||||
});
|
||||
} finally {
|
||||
this.bulkLoading = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadColumnSettings();
|
||||
|
|
|
@ -33,6 +33,7 @@ export default defineComponent({
|
|||
ftpUsername: '',
|
||||
ftpPassword: '',
|
||||
ftpPath: '',
|
||||
taxSystemSandboxMode: false,
|
||||
},
|
||||
dialogVisible: false,
|
||||
dialogMessage: '',
|
||||
|
@ -56,6 +57,7 @@ export default defineComponent({
|
|||
appUrl: data.appUrl || '',
|
||||
appSlogan: data.appSlogan || '',
|
||||
verifyMobileViaSms: data.verifyMobileViaSms || false,
|
||||
taxSystemSandboxMode: data.taxSystemSandboxMode || false,
|
||||
};
|
||||
this.checkFreeAccounting();
|
||||
}
|
||||
|
@ -86,6 +88,7 @@ export default defineComponent({
|
|||
appUrl: this.settings.appUrl,
|
||||
appSlogan: this.settings.appSlogan,
|
||||
verifyMobileViaSms: this.settings.verifyMobileViaSms,
|
||||
taxSystemSandboxMode: this.settings.taxSystemSandboxMode,
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -318,6 +321,13 @@ export default defineComponent({
|
|||
color="primary"
|
||||
></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="4">
|
||||
<v-switch
|
||||
v-model="settings.taxSystemSandboxMode"
|
||||
label="فعال کردن حالت سند باکس سامانه مالیاتی"
|
||||
color="primary"
|
||||
></v-switch>
|
||||
</v-col>
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="4">
|
||||
<v-text-field
|
||||
|
|
Loading…
Reference in a new issue