-
+
@@ -270,7 +262,8 @@
جمع سود موارد انتخاب شده:
-
+
{{ $filters.formatNumber(Math.abs(sumSelectedProfit)) }}
(زیان)
@@ -289,7 +282,8 @@
-
+
@@ -322,39 +316,46 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -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;
@@ -616,7 +617,7 @@ export default defineComponent({
// نمایش متن وضعیت تأیید
getApprovalStatusText(item) {
if (!this.business?.requireTwoStepApproval) return 'تایید دو مرحلهای غیرفعال';
-
+
if (item.isPreview) return 'در انتظار تایید';
if (item.isApproved) return 'تایید شده';
return 'تایید شده';
@@ -624,7 +625,7 @@ export default defineComponent({
// نمایش رنگ وضعیت تأیید
getApprovalStatusColor(item) {
if (!this.business?.requireTwoStepApproval) return 'default';
-
+
if (item.isPreview) return 'warning';
if (item.isApproved) return 'success';
return 'success';
@@ -632,10 +633,10 @@ export default defineComponent({
// بررسی اینکه آیا دکمه تأیید باید نمایش داده شود
canShowApprovalButton(item) {
if (!this.business?.requireTwoStepApproval) return false;
-
+
// اگر سند قبلاً تأیید شده، دکمه تأیید نمایش داده نشود
if (item?.isApproved) return false;
-
+
// مدیر کسب و کار همیشه میتواند تأیید کند
// یا کاربر تأییدکننده فاکتور فروش
return this.business?.invoiceApprover === this.currentUser?.email || this.currentUser?.owner === true;
@@ -645,10 +646,10 @@ export default defineComponent({
try {
this.loading = true;
await axios.post(`/api/approval/approve/sales/${code}`);
-
+
// بهروزرسانی دادهها
await this.loadData();
-
+
Swal.fire({ text: 'فاکتور تایید شد', icon: 'success', confirmButtonText: 'قبول' });
} catch (error) {
Swal.fire({ text: 'خطا در تایید فاکتور: ' + (error.response?.data?.message || error.message), icon: 'error', confirmButtonText: 'قبول' });
@@ -739,7 +740,7 @@ export default defineComponent({
url: '/front/print/' + response.data.id,
responseType: 'arraybuffer'
});
-
+
// ایجاد لینک دانلود
var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
var fileLink = document.createElement('a');
@@ -752,21 +753,37 @@ export default defineComponent({
}
} catch (error) {
console.error('خطا در دریافت فایل PDF:', error);
- Swal.fire({
- text: 'خطا در دریافت فایل PDF',
- icon: 'error',
- confirmButtonText: 'قبول'
- });
+ 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;
- Swal.fire({
- text: 'خطا در ایجاد نسخه PDF',
- icon: 'error',
- confirmButtonText: 'قبول'
- });
+ 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) {
@@ -882,12 +899,12 @@ export default defineComponent({
this.loading = true;
try {
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'),
@@ -933,8 +950,19 @@ 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({
title: 'ارسال گروهی به کارپوشه مودیان',
text: `آیا میخواهید ${selectedCount} فاکتور انتخاب شده را به کارپوشه مودیان ارسال کنید؟`,
@@ -949,18 +977,18 @@ export default defineComponent({
if (result.isConfirmed) {
this.bulkLoading = true;
try {
- const response = await axios.post('/api/plugins/tax/list/send-invoice', {
- codes: this.itemsSelected
+ 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++;
@@ -969,18 +997,18 @@ export default defineComponent({
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, ' '),
@@ -992,9 +1020,9 @@ export default defineComponent({
this.$router.push('/acc/plugins/tax/invoices/list');
}
});
-
+
this.itemsSelected = [];
-
+
} else {
Swal.fire({
text: response.data.message || 'خطا در ارسال گروهی فاکتورها',
@@ -1091,7 +1119,7 @@ export default defineComponent({
flex-direction: column;
gap: 8px;
}
-
+
.summary-item {
min-width: 100%;
justify-content: space-between;
diff --git a/webUI/src/views/acc/settings/bussiness.vue b/webUI/src/views/acc/settings/bussiness.vue
index e471896..4a88dff 100755
--- a/webUI/src/views/acc/settings/bussiness.vue
+++ b/webUI/src/views/acc/settings/bussiness.vue
@@ -24,7 +24,10 @@
{{ $t('dialog.global_settings') }}
-
+
+ {{ $t('dialog.warranty_settings') }}
+
+
نسخه پشتیبان
@@ -195,6 +198,63 @@
+
+
+
+ تنظیمات گارانتی
+
+
+
+
+
+ رفتار گارانتی در حواله خروج
+
+
+
+
+
+
+
+
+
+
+
+
+ نکات
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -534,7 +594,7 @@
-
+
نسخه پشتیبان از اطلاعات کسب و کار
@@ -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)
diff --git a/webUI/src/views/acc/storeroom/io/view.vue b/webUI/src/views/acc/storeroom/io/view.vue
index 8a98756..ccb4a83 100755
--- a/webUI/src/views/acc/storeroom/io/view.vue
+++ b/webUI/src/views/acc/storeroom/io/view.vue
@@ -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)
}
}
|