progress in view invoice sell
This commit is contained in:
parent
474a1eff10
commit
6d63f427ac
134
webUI/src/components/widgets/PrintOptions.vue
Normal file
134
webUI/src/components/widgets/PrintOptions.vue
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'PrintOptions',
|
||||||
|
props: {
|
||||||
|
invoiceId: { type: String, required: true },
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
dialog: false,
|
||||||
|
loading: false,
|
||||||
|
printOptions: {
|
||||||
|
pays: true,
|
||||||
|
note: true,
|
||||||
|
bidInfo: true,
|
||||||
|
taxInfo: true,
|
||||||
|
discountInfo: true,
|
||||||
|
paper: 'A4-L',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
methods: {
|
||||||
|
printInvoice(pdf = true, cloudPrinters = true) {
|
||||||
|
this.loading = true;
|
||||||
|
axios
|
||||||
|
.post('/api/sell/print/invoice', {
|
||||||
|
code: this.$props.invoiceId,
|
||||||
|
pdf,
|
||||||
|
printers: cloudPrinters,
|
||||||
|
printOptions: this.printOptions,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
window.open(`${this.$API_URL}/front/print/${response.data.id}`, '_blank', 'noreferrer');
|
||||||
|
this.dialog = false;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('خطا در چاپ:', error);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// متد برای جلوگیری از بسته شدن دیالوگ با کلیک خارج
|
||||||
|
preventClose() {
|
||||||
|
// هیچ عملی انجام نمیشود تا دیالوگ بسته نشود
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-btn icon color="primary" class="ml-2" @click="dialog = true">
|
||||||
|
<v-icon>mdi-printer</v-icon>
|
||||||
|
<v-tooltip activator="parent" location="bottom">چاپ فاکتور</v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-dialog
|
||||||
|
v-model="dialog"
|
||||||
|
max-width="500"
|
||||||
|
persistent
|
||||||
|
@click:outside="preventClose"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-toolbar color="grey-lighten-4" flat>
|
||||||
|
<v-toolbar-title>
|
||||||
|
<v-icon color="primary" left>mdi-printer</v-icon>
|
||||||
|
چاپ فاکتور
|
||||||
|
</v-toolbar-title>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
color="green"
|
||||||
|
:loading="loading"
|
||||||
|
@click="printInvoice"
|
||||||
|
class="mx-1"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-printer</v-icon>
|
||||||
|
<v-tooltip activator="parent" location="bottom">چاپ فاکتور</v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn icon @click="dialog = false" :disabled="loading">
|
||||||
|
<v-icon>mdi-close</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-toolbar>
|
||||||
|
<v-card-text class="pt-4">
|
||||||
|
<p class="mb-2">برای تغییر تنظیمات پیشفرض به بخش تنظیمات چاپ مراجعه نمایید</p>
|
||||||
|
<v-select
|
||||||
|
v-model="printOptions.paper"
|
||||||
|
:items="[
|
||||||
|
{ title: 'A4 افقی', value: 'A4-L' },
|
||||||
|
{ title: 'A4 عمودی', value: 'A4' },
|
||||||
|
{ title: 'A5 افقی', value: 'A5-L' },
|
||||||
|
{ title: 'A5 عمودی', value: 'A5' },
|
||||||
|
]"
|
||||||
|
label="سایز کاغذ و حالت چاپ"
|
||||||
|
variant="outlined"
|
||||||
|
></v-select>
|
||||||
|
<v-switch
|
||||||
|
v-model="printOptions.bidInfo"
|
||||||
|
label="اطلاعات کسبوکار"
|
||||||
|
class="my-1"
|
||||||
|
hide-details
|
||||||
|
></v-switch>
|
||||||
|
<v-switch
|
||||||
|
v-model="printOptions.pays"
|
||||||
|
label="نمایش پرداختهای فاکتور"
|
||||||
|
class="my-1"
|
||||||
|
hide-details
|
||||||
|
></v-switch>
|
||||||
|
<v-switch
|
||||||
|
v-model="printOptions.note"
|
||||||
|
label="یادداشت پایین فاکتور"
|
||||||
|
class="my-1"
|
||||||
|
hide-details
|
||||||
|
></v-switch>
|
||||||
|
<v-switch
|
||||||
|
v-model="printOptions.taxInfo"
|
||||||
|
label="مالیات به تفکیک اقلام"
|
||||||
|
class="my-1"
|
||||||
|
hide-details
|
||||||
|
></v-switch>
|
||||||
|
<v-switch
|
||||||
|
v-model="printOptions.discountInfo"
|
||||||
|
label="تخفیف به تفکیک اقلام"
|
||||||
|
class="my-1"
|
||||||
|
hide-details
|
||||||
|
></v-switch>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* استایلهای اضافی در صورت نیاز */
|
||||||
|
</style>
|
157
webUI/src/components/widgets/ShareOptions.vue
Normal file
157
webUI/src/components/widgets/ShareOptions.vue
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ShareOptions',
|
||||||
|
props: {
|
||||||
|
shortlinkUrl: { type: String, required: true },
|
||||||
|
mobile: { type: String, required: true },
|
||||||
|
invoiceId: { type: Number, required: true },
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
dialog: false,
|
||||||
|
internalMobile: '',
|
||||||
|
copyLabel: ref('کپی'),
|
||||||
|
messageHint: ref('ارسال'),
|
||||||
|
hintColor: ref('grey'),
|
||||||
|
loading: ref(false),
|
||||||
|
}),
|
||||||
|
created() {
|
||||||
|
this.internalMobile = this.mobile;
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
copyToClipboard() {
|
||||||
|
navigator.clipboard.writeText(this.shortlinkUrl);
|
||||||
|
this.copyLabel = 'کپی شد!';
|
||||||
|
},
|
||||||
|
sendSMS() {
|
||||||
|
this.loading = true;
|
||||||
|
const regex = new RegExp('^(\\+98|0)?9\\d{9}$');
|
||||||
|
if (!regex.test(this.internalMobile)) {
|
||||||
|
this.messageHint = 'شماره موبایل نامعتبر است.';
|
||||||
|
this.hintColor = 'red';
|
||||||
|
this.loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.messageHint = 'در حال ارسال...';
|
||||||
|
this.hintColor = 'grey';
|
||||||
|
axios
|
||||||
|
.post(`/api/sms/send/sell-invoice/${this.invoiceId}/${this.internalMobile}`)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data.result == 2) {
|
||||||
|
this.messageHint = 'اعتبار سرویس پیامک کافی نیست.';
|
||||||
|
this.hintColor = 'red';
|
||||||
|
} else if (response.data.result == 1) {
|
||||||
|
this.messageHint = 'پیامک ارسال شد!';
|
||||||
|
this.hintColor = 'green';
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('خطا در ارسال پیامک:', error);
|
||||||
|
this.messageHint = 'خطا در ارسال پیامک رخ داد.';
|
||||||
|
this.hintColor = 'red';
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-btn icon color="success" class="ml-2" @click="dialog = true">
|
||||||
|
<v-icon>mdi-share-variant</v-icon>
|
||||||
|
<v-tooltip activator="parent" location="bottom">اشتراکگذاری</v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-dialog v-model="dialog" max-width="500" persistent>
|
||||||
|
<v-card>
|
||||||
|
<v-toolbar color="grey-lighten-4" flat>
|
||||||
|
<v-toolbar-title>
|
||||||
|
<v-icon color="success" left>mdi-share-variant</v-icon>
|
||||||
|
اشتراکگذاری
|
||||||
|
</v-toolbar-title>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn icon @click="dialog = false">
|
||||||
|
<v-icon>mdi-close</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-toolbar>
|
||||||
|
<v-card-text>
|
||||||
|
<v-text-field
|
||||||
|
v-model="shortlinkUrl"
|
||||||
|
readonly
|
||||||
|
append-inner-icon="mdi-content-copy"
|
||||||
|
@click:append-inner="copyToClipboard"
|
||||||
|
label="پیوند فاکتور"
|
||||||
|
variant="outlined"
|
||||||
|
:hint="copyLabel"
|
||||||
|
></v-text-field>
|
||||||
|
<v-text-field
|
||||||
|
class="mt-4"
|
||||||
|
v-model="internalMobile"
|
||||||
|
label="ارسال پیامک"
|
||||||
|
variant="outlined"
|
||||||
|
:hint="messageHint"
|
||||||
|
:color="hintColor"
|
||||||
|
persistent-hint
|
||||||
|
>
|
||||||
|
<template v-slot:append-inner>
|
||||||
|
<v-btn
|
||||||
|
color="primary"
|
||||||
|
:loading="loading"
|
||||||
|
@click="sendSMS"
|
||||||
|
>
|
||||||
|
ارسال
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
<div class="mt-3">
|
||||||
|
<v-icon left>mdi-share-variant</v-icon>
|
||||||
|
اشتراکگذاری در شبکههای اجتماعی
|
||||||
|
<div class="mt-2">
|
||||||
|
<!-- تلگرام -->
|
||||||
|
<a
|
||||||
|
:href="'https://t.me/share/url?url=' + encodeURIComponent(shortlinkUrl)"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img src="/img/icons/telegram.png" class="m-3" style="max-width: 30px;" />
|
||||||
|
</a>
|
||||||
|
<!-- ایتا -->
|
||||||
|
<a
|
||||||
|
:href="'https://eitaa.com/?text=' + encodeURIComponent(shortlinkUrl)"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img src="/img/icons/eitaa.jpeg" class="m-3" style="max-width: 30px;" />
|
||||||
|
</a>
|
||||||
|
<!-- بله -->
|
||||||
|
<a
|
||||||
|
:href="'https://ble.ir/share/url?url=' + encodeURIComponent(shortlinkUrl)"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img src="/img/icons/bale-logo.png" class="m-3" style="max-width: 30px;" />
|
||||||
|
</a>
|
||||||
|
<!-- روبیکا -->
|
||||||
|
<a
|
||||||
|
:href="'https://rubika.ir/app/share?text=' + encodeURIComponent(shortlinkUrl)"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img src="/img/icons/robika.png" class="m-3" style="max-width: 30px;" />
|
||||||
|
</a>
|
||||||
|
<!-- واتساپ -->
|
||||||
|
<a
|
||||||
|
:href="'https://api.whatsapp.com/send?text=' + encodeURIComponent(shortlinkUrl)"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<v-icon class="m-3" size="30" color="green">mdi-whatsapp</v-icon>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* استایلهای اضافی در صورت نیاز */
|
||||||
|
</style>
|
|
@ -1,80 +1,82 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {defineComponent} from 'vue'
|
import { defineComponent } from 'vue';
|
||||||
import axios from "axios";
|
import axios from 'axios';
|
||||||
import Swal from "sweetalert2";
|
import Swal from 'sweetalert2';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "archiveUpload",
|
name: 'archiveUpload',
|
||||||
props: {
|
props: {
|
||||||
doctype: String,
|
doctype: String,
|
||||||
docid: [String, Number],
|
docid: [String, Number],
|
||||||
cat: String
|
cat: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
dialog: false, // برای باز و بسته کردن دیالوگ
|
||||||
fileStack: [],
|
fileStack: [],
|
||||||
des: '',
|
des: '',
|
||||||
media: {
|
media: {
|
||||||
saved: [],
|
saved: [],
|
||||||
added: [],
|
added: [],
|
||||||
removed: []
|
removed: [],
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getFilesList();
|
this.getFilesList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeMedia(media) {
|
changeMedia(media) {
|
||||||
this.media = media
|
this.media = media;
|
||||||
},
|
},
|
||||||
addMedia(addedImage, addedMedia) {
|
addMedia(addedImage, addedMedia) {
|
||||||
this.media.added = addedMedia
|
this.media.added = addedMedia;
|
||||||
},
|
},
|
||||||
removeMedia(removedImage, removedMedia) {
|
removeMedia(removedImage, removedMedia) {
|
||||||
this.media.removed = removedMedia
|
this.media.removed = removedMedia;
|
||||||
},
|
},
|
||||||
getFilesList() {
|
getFilesList() {
|
||||||
axios.post('api/archive/files/list',{
|
axios.post('/api/archive/files/list', {
|
||||||
id: this.$props.docid,
|
id: this.$props.docid,
|
||||||
type:this.$props.doctype
|
type: this.$props.doctype,
|
||||||
}).then((resp) => {
|
}).then((resp) => {
|
||||||
this.media.added = [];
|
this.media.added = [];
|
||||||
this.fileStack = resp.data;
|
this.fileStack = resp.data;
|
||||||
this.fileStack.forEach((item) => {
|
this.fileStack.forEach((item) => {
|
||||||
axios.post(this.$filters.getApiUrl() + '/api/archive/file/get/' + item.id, { responseType: "arraybuffer" })
|
axios
|
||||||
|
.post(`${this.$filters.getApiUrl()}/api/archive/file/get/${item.id}`, { responseType: 'arraybuffer' })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const b64 = btoa(String.fromCharCode(...new Uint8Array(response.data)));
|
const b64 = btoa(String.fromCharCode(...new Uint8Array(response.data)));
|
||||||
item.fileBin = "data:" + response.headers['content-type'] + ";base64," + b64;
|
item.fileBin = `data:${response.headers['content-type']};base64,${b64}`;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
deleteItem(item) {
|
deleteItem(item) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
text: 'آیا برای حذف فایل مطمئن هستید؟',
|
text: 'آیا برای حذف فایل مطمئن هستید؟',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonText: 'بله',
|
confirmButtonText: 'بله',
|
||||||
cancelButtonText: `خیر`,
|
cancelButtonText: 'خیر',
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
/* Read more about isConfirmed, isDenied below */
|
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
axios.post('api/archive/file/remove/' + item.id).then((response)=>{
|
axios.post(`/api/archive/file/remove/${item.id}`).then((response) => {
|
||||||
if(response.data.result == 1){
|
if (response.data.result === 1) {
|
||||||
this.getFilesList();
|
this.getFilesList();
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
text: 'فایل با موفقیت حذف شد.',
|
text: 'فایل با موفقیت حذف شد.',
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
confirmButtonText: 'قبول'
|
confirmButtonText: 'قبول',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
downloadFile(item) {
|
downloadFile(item) {
|
||||||
axios.post(this.$filters.getApiUrl() + '/api/archive/file/get/' + item.id, { responseType: "arraybuffer" })
|
axios
|
||||||
.then(response => {
|
.post(`${this.$filters.getApiUrl()}/api/archive/file/get/${item.id}`, { responseType: 'arraybuffer' })
|
||||||
|
.then((response) => {
|
||||||
const blob = new Blob([response.data], { type: item.fileType });
|
const blob = new Blob([response.data], { type: item.fileType });
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = URL.createObjectURL(blob);
|
link.href = URL.createObjectURL(blob);
|
||||||
|
@ -84,56 +86,74 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
submitArchive() {
|
submitArchive() {
|
||||||
let formData = new FormData(document.getElementById('archive-file-upload'))
|
const formData = new FormData(document.getElementById('archive-file-upload'));
|
||||||
axios.post('api/archive/file/save',formData,{
|
axios
|
||||||
|
.post('/api/archive/file/save', formData, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'multipart/form-data',
|
||||||
}
|
},
|
||||||
}).then((resp)=>{
|
})
|
||||||
|
.then((resp) => {
|
||||||
if (resp.data.result === 'nem') {
|
if (resp.data.result === 'nem') {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
text: 'فضای کافی وجود ندارد لطفا حساب کاربری خود را شارژ نمایید.',
|
text: 'فضای کافی وجود ندارد لطفا حساب کاربری خود را شارژ نمایید.',
|
||||||
icon: 'success',
|
icon: 'error',
|
||||||
confirmButtonText: 'قبول'
|
confirmButtonText: 'قبول',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
text: 'فایلهای انتخابی ذخیره شدند.',
|
text: 'فایلهای انتخابی ذخیره شدند.',
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
confirmButtonText: 'قبول'
|
confirmButtonText: 'قبول',
|
||||||
});
|
});
|
||||||
this.getFilesList();
|
this.getFilesList();
|
||||||
|
this.des = ''; // ریست کردن توضیحات
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('خطا در آپلود:', error);
|
||||||
|
Swal.fire({
|
||||||
|
text: 'خطایی در بارگذاری فایل رخ داد.',
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: 'قبول',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- Button trigger modal -->
|
<!-- دکمه در تولبار -->
|
||||||
<button type="button" class="btn btn-sm btn-outline-success mx-2" data-bs-toggle="modal" data-bs-target="#archiveModal">
|
<v-btn icon color="success" class="ml-2" @click="dialog = true">
|
||||||
<span class="badge text-bg-dark me-2">{{fileStack.length}}</span>
|
<v-badge :content="fileStack.length.toString()" color="dark">
|
||||||
<i class="fa fa-file me-1"></i>
|
<v-icon>mdi-archive</v-icon>
|
||||||
<span class="d-none d-sm-inline-block">آرشیو</span>
|
</v-badge>
|
||||||
</button>
|
<v-tooltip activator="parent" location="bottom">آرشیو</v-tooltip>
|
||||||
<!-- Modal -->
|
</v-btn>
|
||||||
<div class="modal modal-lg fade" data-bs-backdrop="static" data-bs-keyboard="false" id="archiveModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog">
|
<!-- دیالوگ آرشیو -->
|
||||||
<div class="modal-content">
|
<v-dialog v-model="dialog" max-width="800" persistent>
|
||||||
<div class="modal-header">
|
<v-card>
|
||||||
<h1 class="modal-title fs-5" id="exampleModalLabel">آرشیو فایل</h1>
|
<v-toolbar color="grey-lighten-4" flat>
|
||||||
<div class="block-options">
|
<v-toolbar-title>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<v-icon color="success" left>mdi-archive</v-icon>
|
||||||
</div>
|
آرشیو فایل
|
||||||
</div>
|
</v-toolbar-title>
|
||||||
<div class="modal-body">
|
<v-spacer></v-spacer>
|
||||||
<h5 class="text-primary-dark mt-3 my-0 py-0">افزودن فایل جدید</h5>
|
<v-btn icon @click="dialog = false">
|
||||||
<div>
|
<v-icon>mdi-close</v-icon>
|
||||||
<form id="archive-file-upload" @submit.prevent="submitArchive()">
|
</v-btn>
|
||||||
<input type="hidden" name="doctype" :value="$props.doctype">
|
</v-toolbar>
|
||||||
<input type="hidden" name="docid" :value="$props.docid">
|
|
||||||
<input type="hidden" name="cat" :value="$props.cat">
|
<v-card-text>
|
||||||
|
<!-- بخش افزودن فایل جدید -->
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<form id="archive-file-upload" @submit.prevent="submitArchive">
|
||||||
|
<input type="hidden" name="doctype" :value="$props.doctype" />
|
||||||
|
<input type="hidden" name="docid" :value="$props.docid" />
|
||||||
|
<input type="hidden" name="cat" :value="$props.cat" />
|
||||||
<Uploader
|
<Uploader
|
||||||
:server="$filters.getApiUrl() + '/api/archive/file/upload'"
|
:server="$filters.getApiUrl() + '/api/archive/file/upload'"
|
||||||
:media="media.saved"
|
:media="media.saved"
|
||||||
|
@ -143,68 +163,67 @@ export default defineComponent({
|
||||||
@change="changeMedia"
|
@change="changeMedia"
|
||||||
:maxFilesize="5"
|
:maxFilesize="5"
|
||||||
/>
|
/>
|
||||||
<div class="container-fluid mt-2">
|
<v-text-field
|
||||||
<div class="row">
|
v-model="des"
|
||||||
<div class="col-9">
|
label="توضیحات"
|
||||||
<input class="form-control" type="text" name="des" v-model="des" placeholder="توضیحات" aria-label="توضیحات">
|
placeholder="توضیحات"
|
||||||
</div>
|
outlined
|
||||||
<div class="col-3">
|
name="des"
|
||||||
<button type="submit" class="btn btn-success d-flex">
|
class="mt-2"
|
||||||
<i class="fa fa-save me-2"></i>
|
></v-text-field>
|
||||||
|
<v-btn type="submit" color="success" class="mt-2">
|
||||||
|
<v-icon left>mdi-content-save</v-icon>
|
||||||
بارگذاری فایلها
|
بارگذاری فایلها
|
||||||
</button>
|
</v-btn>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</v-col>
|
||||||
<hr>
|
</v-row>
|
||||||
<h5 class="text-primary-dark mt-3 mb-0 pb-0">آرشیو فایلها</h5>
|
|
||||||
<table class="table table-striped table-hover table-borderless table-vcenter fs-sm text-center">
|
<v-divider class="my-4"></v-divider>
|
||||||
|
|
||||||
|
<!-- لیست فایلها -->
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<h5 class="text-primary">آرشیو فایلها</h5>
|
||||||
|
<v-table class="elevation-1">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="text-uppercase">
|
<tr>
|
||||||
<th>پیش نمایش</th>
|
<th class="text-center">پیشنمایش</th>
|
||||||
<th>نام فایل</th>
|
<th class="text-center">نام فایل</th>
|
||||||
<th class="">سایز فایل(مگابایت)</th>
|
<th class="text-center">سایز فایل (مگابایت)</th>
|
||||||
<th class="">تاریخ</th>
|
<th class="text-center">تاریخ</th>
|
||||||
<th>عملیات</th>
|
<th class="text-center">عملیات</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="item in fileStack">
|
<tr v-for="item in fileStack" :key="item.id">
|
||||||
<td>
|
<td class="text-center">
|
||||||
<img class="img-fluid" :src="item.fileBin" alt="پیش نمایش">
|
<v-img :src="item.fileBin" max-width="50" max-height="50" class="mx-auto" alt="پیشنمایش" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="text-center">{{ item.filename }}</td>
|
||||||
<span class="fw-semibold">{{item.filename}}</span>
|
<td class="text-center">{{ item.filesize }}</td>
|
||||||
</td>
|
<td class="text-center">{{ item.dateSubmit }}</td>
|
||||||
<td>
|
<td class="text-center">
|
||||||
<span>{{item.filesize}}</span>
|
<v-btn icon small color="primary" @click="downloadFile(item)">
|
||||||
</td>
|
<v-icon>mdi-download</v-icon>
|
||||||
<td>
|
</v-btn>
|
||||||
<span>{{item.dateSubmit}}</span>
|
<v-btn icon small color="error" class="ml-2" @click="deleteItem(item)">
|
||||||
</td>
|
<v-icon>mdi-trash-can</v-icon>
|
||||||
<td class="text-center text-nowrap fw-medium">
|
</v-btn>
|
||||||
<a class="btn btn-sm btn-link" href="/" @click.prevent="downloadFile(item)">
|
|
||||||
<i class="fa fa-download"></i>
|
|
||||||
</a>
|
|
||||||
<button @click="deleteItem(item)" class="btn btn-sm ms-2 btn-link text-danger">
|
|
||||||
<i class="fa fa-trash"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr v-if="fileStack.length === 0">
|
||||||
|
<td colspan="5" class="text-center text-muted">فایلی موجود نیست</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</v-table>
|
||||||
</div>
|
</v-col>
|
||||||
<div class="modal-footer">
|
</v-row>
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">بازگشت</button>
|
</v-card-text>
|
||||||
</div>
|
</v-card>
|
||||||
</div>
|
</v-dialog>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* استایلهای اضافی اگه نیاز باشه */
|
||||||
</style>
|
</style>
|
|
@ -1,34 +1,37 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineComponent } from 'vue'
|
|
||||||
import Swal from "sweetalert2";
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import Loading from 'vue-loading-overlay';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "notes",
|
name: 'Notes',
|
||||||
components:{
|
|
||||||
Loading
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
stat: Object,
|
stat: Object,
|
||||||
code: String,
|
code: String,
|
||||||
typeNote: String
|
typeNote: String,
|
||||||
},
|
},
|
||||||
data: () => {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: ref(true),
|
dialog: false, // برای باز و بسته کردن دیالوگ
|
||||||
|
loading: false,
|
||||||
items: [],
|
items: [],
|
||||||
des: '',
|
des: '',
|
||||||
}
|
snackbar: false, // برای نمایش اسنکبار
|
||||||
|
snackbarText: '', // متن پیام اسنکبار
|
||||||
|
snackbarColor: 'success', // رنگ اسنکبار (success, error)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loadData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadData() {
|
loadData() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
axios.post('/api/notes/list', {
|
axios
|
||||||
|
.post('/api/notes/list', {
|
||||||
type: this.$props.typeNote,
|
type: this.$props.typeNote,
|
||||||
code: this.$props.code
|
code: this.$props.code,
|
||||||
}).then((response) => {
|
})
|
||||||
|
.then((response) => {
|
||||||
this.items = response.data;
|
this.items = response.data;
|
||||||
this.$props.stat.count = response.data.length;
|
this.$props.stat.count = response.data.length;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
@ -36,92 +39,172 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
remove(id) {
|
remove(id) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
axios.post('/api/notes/remove/' + id).then((response) => {
|
axios.post(`/api/notes/remove/${id}`).then((response) => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
Swal.fire({
|
this.items = this.items.filter(item => item.id !== id); // حذف از لیست محلی
|
||||||
text: ' با موفقیت حذف شد.',
|
this.$props.stat.count = this.items.length; // بهروزرسانی تعداد
|
||||||
icon: 'success',
|
this.snackbarText = 'یادداشت با موفقیت حذف شد.';
|
||||||
confirmButtonText: 'قبول'
|
this.snackbarColor = 'success';
|
||||||
}).then((result) => {
|
this.snackbar = true;
|
||||||
this.loadData();
|
}).catch((error) => {
|
||||||
|
this.loading = false;
|
||||||
|
this.snackbarText = 'خطایی در حذف یادداشت رخ داد.';
|
||||||
|
this.snackbarColor = 'error';
|
||||||
|
this.snackbar = true;
|
||||||
|
console.error('خطا:', error);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
},
|
},
|
||||||
save() {
|
save() {
|
||||||
if (this.des.trim() == '') {
|
if (this.des.trim() === '') {
|
||||||
Swal.fire({
|
this.snackbarText = 'شرح الزامی است.';
|
||||||
text: 'شرح الزامی است.',
|
this.snackbarColor = 'error';
|
||||||
icon: 'error',
|
this.snackbar = true;
|
||||||
confirmButtonText: 'قبول'
|
} else {
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
axios.post('/api/notes/add', {
|
axios
|
||||||
|
.post('/api/notes/add', {
|
||||||
des: this.des,
|
des: this.des,
|
||||||
type: this.$props.typeNote,
|
type: this.$props.typeNote,
|
||||||
code: this.$route.params.id
|
code: this.$route.params.id,
|
||||||
}).then((response) => {
|
|
||||||
this.loading = false;
|
|
||||||
Swal.fire({
|
|
||||||
text: ' با موفقیت ثبت شد.',
|
|
||||||
icon: 'success',
|
|
||||||
confirmButtonText: 'قبول'
|
|
||||||
}).then((result) => {
|
|
||||||
this.loadData();
|
|
||||||
this.des = '';
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
}
|
.then((response) => {
|
||||||
|
this.loading = false;
|
||||||
|
// اضافه کردن یادداشت جدید به لیست محلی
|
||||||
|
this.items.unshift({
|
||||||
|
id: response.data.id, // فرض میکنیم سرور id رو برمیگردونه
|
||||||
|
des: this.des,
|
||||||
|
});
|
||||||
|
this.$props.stat.count = this.items.length; // بهروزرسانی تعداد
|
||||||
|
this.snackbarText = 'یادداشت با موفقیت ثبت شد.';
|
||||||
|
this.snackbarColor = 'success';
|
||||||
|
this.snackbar = true;
|
||||||
|
this.des = ''; // ریست کردن ورودی
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.loading = false;
|
||||||
|
this.snackbarText = 'خطایی در ثبت یادداشت رخ داد.';
|
||||||
|
this.snackbarColor = 'error';
|
||||||
|
this.snackbar = true;
|
||||||
|
console.error('خطا:', error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
},
|
||||||
this.loadData();
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- Modal -->
|
<!-- دکمه در تولبار -->
|
||||||
<div class="modal modal-lg fade" id="notesModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
|
<v-btn icon color="warning" class="ml-2" @click="dialog = true">
|
||||||
aria-labelledby="notesModalLabel" aria-hidden="true">
|
<v-badge :content="items.length.toString()" color="dark">
|
||||||
<div class="modal-dialog">
|
<v-icon>mdi-note</v-icon>
|
||||||
<div class="modal-content">
|
</v-badge>
|
||||||
<div class="modal-header bg-warning text-white">
|
<v-tooltip activator="parent" location="bottom">یادداشتها</v-tooltip>
|
||||||
<h1 class="modal-title fs-5" id="notesModalLabel">
|
</v-btn>
|
||||||
<i class="fa-regular fa-note-sticky me-1"></i>
|
|
||||||
|
<!-- دیالوگ یادداشتها -->
|
||||||
|
<v-dialog v-model="dialog" max-width="600" persistent>
|
||||||
|
<v-card>
|
||||||
|
<v-toolbar color="toolbar" flat dark>
|
||||||
|
<v-toolbar-title>
|
||||||
|
<v-icon color="warning" left>mdi-note</v-icon>
|
||||||
یادداشتها
|
یادداشتها
|
||||||
</h1>
|
</v-toolbar-title>
|
||||||
<div class="block-options">
|
<v-spacer></v-spacer>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<v-btn icon @click="dialog = false">
|
||||||
</div>
|
<v-icon>mdi-close</v-icon>
|
||||||
</div>
|
</v-btn>
|
||||||
<div class="modal-body">
|
</v-toolbar>
|
||||||
<div class="input-group mb-3">
|
|
||||||
<input v-model="des" type="text" class="form-control" placeholder="شرح" aria-label="افزودن یادداشت"
|
<v-card-text>
|
||||||
aria-describedby="button-addon1">
|
<!-- فرم افزودن یادداشت -->
|
||||||
<button :disabled="this.loading" @click="save()" class="btn btn-outline-success" type="button"
|
<v-row>
|
||||||
id="button-addon1">ثبت</button>
|
<v-col cols="12">
|
||||||
</div>
|
<v-text-field
|
||||||
<Loading color="blue" loader="dots" v-model:active="loading" :is-full-page="false"/>
|
v-model="des"
|
||||||
<ul :disabled="this.loading" class="list-group">
|
label="شرح"
|
||||||
<li v-for="item in items" class="list-group-item d-flex justify-content-between align-items-center">
|
placeholder="شرح یادداشت"
|
||||||
<span class="">
|
outlined
|
||||||
{{ item.des }}
|
class="mt-2"
|
||||||
</span>
|
:disabled="loading"
|
||||||
<a title="حذف" @click="remove(item.id)" class="text-danger rounded-pill float-start">
|
@keyup.enter="save"
|
||||||
<i class="fa fa-trash"></i>
|
:loading="loading"
|
||||||
</a>
|
></v-text-field>
|
||||||
</li>
|
<v-btn
|
||||||
</ul>
|
color="success"
|
||||||
<div v-if="items.length == 0">
|
@click="save"
|
||||||
نتیجهای یافت نشد
|
class="mt-2"
|
||||||
</div>
|
:loading="loading"
|
||||||
</div>
|
>
|
||||||
</div>
|
<v-icon left>mdi-content-save</v-icon>
|
||||||
</div>
|
ثبت یادداشت
|
||||||
</div>
|
</v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-divider class="my-4"></v-divider>
|
||||||
|
|
||||||
|
<!-- لیست یادداشتها با اسکرول -->
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<h5 class="text-primary">یادداشتهای ثبتشده</h5>
|
||||||
|
<v-list
|
||||||
|
max-height="300"
|
||||||
|
class="overflow-y-auto"
|
||||||
|
>
|
||||||
|
<v-list-item
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item.id"
|
||||||
|
class="my-1"
|
||||||
|
>
|
||||||
|
<v-list-item-title class="d-flex align-center">
|
||||||
|
<span>{{ item.des }}</span>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
variant="plain"
|
||||||
|
:disabled="loading"
|
||||||
|
@click="remove(item.id)"
|
||||||
|
>
|
||||||
|
<v-icon color="error">mdi-trash-can</v-icon>
|
||||||
|
<v-tooltip activator="parent" location="top">حذف</v-tooltip>
|
||||||
|
</v-btn>
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="items.length === 0">
|
||||||
|
<v-list-item-title class="text-muted text-center">
|
||||||
|
یادداشتی موجود نیست
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
<!-- اسنکبار برای نمایش پیامها -->
|
||||||
|
<v-snackbar
|
||||||
|
v-model="snackbar"
|
||||||
|
:color="snackbarColor"
|
||||||
|
timeout="3000"
|
||||||
|
location="top"
|
||||||
|
>
|
||||||
|
{{ snackbarText }}
|
||||||
|
<template v-slot:actions>
|
||||||
|
<v-btn
|
||||||
|
color="white"
|
||||||
|
variant="text"
|
||||||
|
@click="snackbar = false"
|
||||||
|
>
|
||||||
|
بستن
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-snackbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.overflow-y-auto {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,85 +1,56 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from 'vue'
|
import { defineComponent, ref } from 'vue';
|
||||||
import axios from "axios";
|
import axios from 'axios';
|
||||||
import Swal from "sweetalert2";
|
import Swal from 'sweetalert2';
|
||||||
import rec from "../component/rec.vue";
|
import Rec from '../component/rec.vue';
|
||||||
import recList from "../component/recList.vue";
|
import RecList from '../component/recList.vue';
|
||||||
import ArchiveUpload from "../component/archive/archiveUpload.vue";
|
import ArchiveUpload from '../component/archive/archiveUpload.vue';
|
||||||
import type { Header, Item } from "vue3-easy-data-table";
|
import Notes from '../component/notes.vue';
|
||||||
import { getApiUrl } from "@/hesabixConfig";
|
import PrintOptions from '@/components/widgets/PrintOptions.vue';
|
||||||
import notes from '../component/notes.vue';
|
import ShareOptions from '@/components/widgets/ShareOptions.vue';
|
||||||
|
import { getApiUrl } from '@/hesabixConfig';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "viewInvoice",
|
name: 'viewInvoice',
|
||||||
components: {
|
components: {
|
||||||
ArchiveUpload,
|
ArchiveUpload,
|
||||||
rec: rec,
|
Rec,
|
||||||
recList: recList,
|
RecList,
|
||||||
notes
|
Notes,
|
||||||
|
PrintOptions,
|
||||||
|
ShareOptions,
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'PayWindowsState.submited'(newValue, oldValue) {
|
'PayWindowsState.submited'(newValue) {
|
||||||
this.PayWindowsState.submited = false;
|
this.PayWindowsState.submited = false;
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
this.loadData();
|
this.loadData();
|
||||||
this.recModal.hide()
|
this.recDialog = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'recListWindowsState.submited'(newValue, oldValue) {
|
'recListWindowsState.submited'(newValue) {
|
||||||
this.recListWindowsState.submited = false;
|
this.recListWindowsState.submited = false;
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
this.loadData();
|
this.loadData();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data: () => {
|
|
||||||
return {
|
|
||||||
printOptions: {
|
|
||||||
pays: true,
|
|
||||||
note: true,
|
|
||||||
bidInfo: true,
|
|
||||||
taxInfo: true,
|
|
||||||
discountInfo: true,
|
|
||||||
paper: 'A4-L'
|
|
||||||
},
|
},
|
||||||
notes: {
|
data: () => ({
|
||||||
count: 0
|
recDialog: false,
|
||||||
},
|
recListDialog: false,
|
||||||
PayWindowsState: {
|
activeTab: 'invoice-info',
|
||||||
submited: false
|
|
||||||
},
|
|
||||||
recListWindowsState: {
|
|
||||||
submited: false
|
|
||||||
},
|
|
||||||
recModal: {},
|
|
||||||
recListModal: {},
|
|
||||||
loading: ref(true),
|
loading: ref(true),
|
||||||
shortlink_url: '',
|
shortlink_url: '',
|
||||||
copy_label: 'کپی',
|
PayWindowsState: { submited: false },
|
||||||
send_message_label: 'ارسال',
|
recListWindowsState: { submited: false },
|
||||||
bid: {
|
notes: { count: 0 },
|
||||||
legal_name: '',
|
bid: { legal_name: '', shortlinks: false },
|
||||||
shortlinks: false,
|
|
||||||
},
|
|
||||||
item: {
|
item: {
|
||||||
doc: {
|
doc: { id: 0, date: null, code: null, des: '', amount: 0, profit: 0, shortLink: null },
|
||||||
id: 0,
|
|
||||||
date: null,
|
|
||||||
code: null,
|
|
||||||
des: '',
|
|
||||||
amount: 0,
|
|
||||||
profit: 0,
|
|
||||||
shortLink: null,
|
|
||||||
},
|
|
||||||
relatedDocs: [],
|
relatedDocs: [],
|
||||||
rows: []
|
rows: [],
|
||||||
},
|
|
||||||
person: {
|
|
||||||
nikename: null,
|
|
||||||
mobile: '',
|
|
||||||
tel: '',
|
|
||||||
addres: '',
|
|
||||||
postalcode: '',
|
|
||||||
},
|
},
|
||||||
|
person: { nikename: null, mobile: '', tel: '', addres: '', postalcode: '' },
|
||||||
commoditys: [],
|
commoditys: [],
|
||||||
totalRec: 0,
|
totalRec: 0,
|
||||||
totalDiscount: 0,
|
totalDiscount: 0,
|
||||||
|
@ -87,46 +58,63 @@ export default defineComponent({
|
||||||
transferCost: 0,
|
transferCost: 0,
|
||||||
discountAll: 0,
|
discountAll: 0,
|
||||||
mobileHeaders: [
|
mobileHeaders: [
|
||||||
{ text: "کالا", value: "commodity.name" },
|
{ title: 'کالا', key: 'commodity.name' },
|
||||||
{ text: "تعداد", value: "count" },
|
{ title: 'تعداد', key: 'count' },
|
||||||
{ text: "مبلغ کل", value: "sumTotal" },
|
{ title: 'مبلغ کل', key: 'sumTotal' },
|
||||||
]
|
],
|
||||||
}
|
}),
|
||||||
|
computed: {
|
||||||
|
formattedAmount() {
|
||||||
|
return this.$filters.formatNumber(this.item.doc.amount);
|
||||||
|
},
|
||||||
|
statusText() {
|
||||||
|
return parseInt(this.item.doc.amount) <= parseInt(this.totalRec) ? 'تسویه شده' : 'تسویه نشده';
|
||||||
|
},
|
||||||
|
statusColor() {
|
||||||
|
return parseInt(this.item.doc.amount) <= parseInt(this.totalRec) ? 'success' : 'error';
|
||||||
|
},
|
||||||
|
profitText() {
|
||||||
|
return this.$filters.formatNumber(Math.abs(this.item.doc.profit));
|
||||||
|
},
|
||||||
|
profitLabel() {
|
||||||
|
return parseInt(this.item.doc.profit) >= 0 ? 'سود فاکتور' : 'زیان فاکتور';
|
||||||
|
},
|
||||||
|
profitColor() {
|
||||||
|
return parseInt(this.item.doc.profit) >= 0 ? 'success' : 'error';
|
||||||
|
},
|
||||||
|
formattedTotalTax() {
|
||||||
|
return this.$filters.formatNumber(this.totalTax);
|
||||||
|
},
|
||||||
|
formattedDiscountAll() {
|
||||||
|
return this.$filters.formatNumber(this.discountAll);
|
||||||
|
},
|
||||||
|
formattedTransferCost() {
|
||||||
|
return this.$filters.formatNumber(this.transferCost);
|
||||||
},
|
},
|
||||||
setup() {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
copyToCliboard() {
|
|
||||||
navigator.clipboard.writeText(this.shortlink_url);
|
|
||||||
this.copy_label = 'کپی شد !';
|
|
||||||
},
|
|
||||||
loadData() {
|
loadData() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.commoditys = [];
|
this.commoditys = [];
|
||||||
axios.post('/api/accounting/doc/get', { 'code': this.$route.params.id }).then((response) => {
|
axios.post('/api/accounting/doc/get', { code: this.$route.params.id }).then((response) => {
|
||||||
this.item = response.data;
|
this.item = response.data;
|
||||||
if (this.item.doc.shortLink != null) {
|
this.shortlink_url = this.item.doc.shortLink
|
||||||
this.shortlink_url = getApiUrl() + '/sl/sell/' + localStorage.getItem("activeBid") + '/' + this.item.doc.shortLink;
|
? `${getApiUrl()}/sl/sell/${localStorage.getItem('activeBid')}/${this.item.doc.shortLink}`
|
||||||
}
|
: `${getApiUrl()}/sl/sell/${localStorage.getItem('activeBid')}/${this.item.doc.id}`;
|
||||||
else {
|
this.totalRec = response.data.relatedDocs.reduce((sum: number, rdoc: any) => sum + parseInt(rdoc.amount), 0);
|
||||||
this.shortlink_url = getApiUrl() + '/sl/sell/' + localStorage.getItem("activeBid") + '/' + this.item.doc.id;
|
|
||||||
}
|
|
||||||
response.data.relatedDocs.forEach((rdoc: any) => {
|
|
||||||
this.totalRec += parseInt(rdoc.amount)
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
axios.get('/api/sell/get/info/' + this.$route.params.id).then((response) => {
|
axios.get(`/api/sell/get/info/${this.$route.params.id}`).then((response) => {
|
||||||
this.person = response.data.person;
|
this.person = response.data.person;
|
||||||
this.discountAll = response.data.discountAll;
|
this.discountAll = response.data.discountAll;
|
||||||
this.transferCost = response.data.transferCost;
|
this.transferCost = response.data.transferCost;
|
||||||
this.item.doc.profit = response.data.profit;
|
this.item.doc.profit = response.data.profit;
|
||||||
response.data.rows.forEach((item: any) => {
|
this.commoditys = response.data.rows
|
||||||
if (item.commodity != null) {
|
.filter((item: any) => item.commodity != null)
|
||||||
|
.map((item: any) => {
|
||||||
this.totalTax += parseInt(item.tax);
|
this.totalTax += parseInt(item.tax);
|
||||||
this.totalDiscount += parseInt(item.discount);
|
this.totalDiscount += parseInt(item.discount);
|
||||||
this.commoditys.push({
|
return {
|
||||||
commodity: item.commodity,
|
commodity: item.commodity,
|
||||||
count: item.commodity_count,
|
count: item.commodity_count,
|
||||||
price: parseInt((parseInt(item.bs) - parseInt(item.tax) + parseInt(item.discount)) / parseFloat(item.commodity_count)),
|
price: parseInt((parseInt(item.bs) - parseInt(item.tax) + parseInt(item.discount)) / parseFloat(item.commodity_count)),
|
||||||
|
@ -138,499 +126,197 @@ export default defineComponent({
|
||||||
tax: item.tax,
|
tax: item.tax,
|
||||||
sumWithoutTax: item.bs - item.tax,
|
sumWithoutTax: item.bs - item.tax,
|
||||||
sumTotal: item.bs,
|
sumTotal: item.bs,
|
||||||
table: 53
|
table: 53,
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
});
|
axios.post(`/api/business/get/info/${localStorage.getItem('activeBid')}`).then((response) => {
|
||||||
});
|
|
||||||
axios.post('/api/business/get/info/' + localStorage.getItem('activeBid')).then((response) => {
|
|
||||||
this.bid = response.data;
|
this.bid = response.data;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
axios.get("/api/printers/options/info").then((response) => {
|
|
||||||
this.loading = false;
|
|
||||||
this.printOptions = response.data.sell;
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
sendSMS() {
|
|
||||||
this.loading = true;
|
|
||||||
const regex = new RegExp("^(\\+98|0)?9\\d{9}$");
|
|
||||||
if (!regex.test(this.person.mobile)) {
|
|
||||||
Swal.fire({
|
|
||||||
text: 'شماره موبایل وارد شده نا معتبر است.',
|
|
||||||
icon: 'error',
|
|
||||||
confirmButtonText: 'قبول'
|
|
||||||
});
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.send_message_label = 'در حال ارسال...';
|
|
||||||
axios.post('/api/sms/send/sell-invoice/' + this.item.doc.id + '/' + this.person.mobile).then((response) => {
|
|
||||||
if (response.data.result == 2) {
|
|
||||||
Swal.fire({
|
|
||||||
text: 'اعتبار سرویس پیامک کافی نیست.',
|
|
||||||
icon: 'error',
|
|
||||||
confirmButtonText: 'قبول'
|
|
||||||
});
|
|
||||||
this.send_message_label = 'ارسال';
|
|
||||||
}
|
|
||||||
else if (response.data.result == 1) {
|
|
||||||
Swal.fire({
|
|
||||||
text: 'پیامک اطلاع رسانی ارسال شد.',
|
|
||||||
icon: 'success',
|
|
||||||
confirmButtonText: 'قبول'
|
|
||||||
});
|
|
||||||
this.send_message_label = 'ارسال شد!'
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
printInvoice(pdf = true, cloudePrinters = true) {
|
|
||||||
axios.post('/api/sell/print/invoice', {
|
|
||||||
'code': this.$route.params.id,
|
|
||||||
'pdf': pdf,
|
|
||||||
'printers': cloudePrinters,
|
|
||||||
'printOptions': this.printOptions
|
|
||||||
}).then((response) => {
|
|
||||||
window.open(this.$API_URL + '/front/print/' + response.data.id, '_blank', 'noreferrer');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadData();
|
this.loadData();
|
||||||
this.recModal = new bootstrap.Modal(document.getElementById('rec-modal'))
|
},
|
||||||
this.recListModal = new bootstrap.Modal(document.getElementById('rec-list-modal'))
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- Print Modal -->
|
<v-toolbar color="toolbar" flat title="مشاهده فاکتور">
|
||||||
<div class="modal fade" id="printModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
|
<template v-slot:prepend>
|
||||||
aria-labelledby="printModalLabel" aria-hidden="true">
|
<v-tooltip text="بازگشت" location="bottom">
|
||||||
<div class="modal-dialog">
|
<template v-slot:activator="{ props }">
|
||||||
<div class="modal-content">
|
<v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text" icon="mdi-arrow-right" />
|
||||||
<div class="modal-header bg-primary-light text-white">
|
</template>
|
||||||
<h1 class="modal-title fs-5" id="printModalLabel">چاپ فاکتور</h1>
|
</v-tooltip>
|
||||||
<div class="block-options">
|
</template>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<v-spacer></v-spacer>
|
||||||
</div>
|
<v-btn icon v-if="item.doc.id !== 0">
|
||||||
</div>
|
<archive-upload :docid="item.doc.id" doctype="sell" cat="sell" />
|
||||||
<div class="modal-body">
|
<v-tooltip activator="parent" location="bottom">آرشیو</v-tooltip>
|
||||||
<p class="mb-2">برای تغییر تنظیمات پیشفرض به بخش تنظیمات چاپ مراجعه نمایید</p>
|
</v-btn>
|
||||||
<div class="form-floating mb-2">
|
<notes :stat="notes" :code="$route.params.id" type-note="sell" />
|
||||||
<select v-model="printOptions.paper" class="form-select">
|
<v-btn icon color="error" class="ml-2" v-if="parseInt(item.doc.amount) > parseInt(totalRec)" @click="recDialog = true">
|
||||||
<option value="A4-L">A4 افقی</option>
|
<v-icon>mdi-money</v-icon>
|
||||||
<option value="A4">A4 عمودی</option>
|
<v-tooltip activator="parent" location="bottom">ثبت دریافت</v-tooltip>
|
||||||
<option value="A5-L">A5 افقی</option>
|
</v-btn>
|
||||||
<option value="A5">A5 عمودی</option>
|
<v-btn icon color="info" class="ml-2" @click="recListDialog = true">
|
||||||
</select>
|
<v-icon>mdi-arrow-down-circle</v-icon>
|
||||||
<label>سایز کاغذ و حالت چاپ</label>
|
<v-tooltip activator="parent" location="bottom">دریافتها</v-tooltip>
|
||||||
</div>
|
</v-btn>
|
||||||
<div class="form-check form-switch">
|
<share-options v-if="bid.shortlinks" :shortlink-url="shortlink_url" :mobile="person.mobile" :invoice-id="item.doc.id" />
|
||||||
<input class="form-check-input" v-model="printOptions.bidInfo" type="checkbox">
|
<print-options :invoice-id="$route.params.id" />
|
||||||
<label class="form-check-label">اطلاعات کسبوکار</label>
|
</v-toolbar>
|
||||||
</div>
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" v-model="printOptions.pays" type="checkbox">
|
|
||||||
<label class="form-check-label">نمایش پرداختهای فاکتور</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" v-model="printOptions.note" type="checkbox">
|
|
||||||
<label class="form-check-label">یادداشت پایین فاکتور</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" v-model="printOptions.taxInfo" type="checkbox">
|
|
||||||
<label class="form-check-label">مالیات به تفکیک اقلام</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" v-model="printOptions.discountInfo" type="checkbox">
|
|
||||||
<label class="form-check-label">تخفیف به تفکیک اقلام</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button class="btn btn-primary mx-2" @click="printInvoice()" type="button">
|
|
||||||
<i class="si si-printer me-1"></i>
|
|
||||||
<span class="">چاپ</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- End Print Modal -->
|
|
||||||
|
|
||||||
<div class="block block-content-full">
|
<v-tabs v-model="activeTab" color="primary" grow class="mt-0">
|
||||||
<div id="fixed-header" class="block-header block-header-default bg-gray-light">
|
<v-tab value="person-info">اطلاعات شخص</v-tab>
|
||||||
<h3 class="block-title text-primary-dark">
|
<v-tab value="invoice-info">اقلام فاکتور</v-tab>
|
||||||
<button @click="$router.back()" type="button"
|
<v-tab value="payments">دریافتها</v-tab>
|
||||||
class="float-start d-none d-sm-none d-md-block btn btn-sm btn-link text-warning">
|
</v-tabs>
|
||||||
<i class="fa fw-bold fa-arrow-right"></i>
|
<v-container fluid>
|
||||||
</button>
|
<v-window v-model="activeTab">
|
||||||
<i class="fas fa-file-invoice-dollar"></i>
|
<!-- تب اطلاعات شخص -->
|
||||||
مشاهده فاکتور
|
<v-window-item value="person-info">
|
||||||
</h3>
|
<v-card-text>
|
||||||
<div class="block-options">
|
<v-row>
|
||||||
<archive-upload v-if="item.doc.id != 0" :docid="item.doc.id" doctype="sell" cat="sell"></archive-upload>
|
<v-col cols="12" sm="6" md="4">
|
||||||
<button type="button" class="btn btn-sm btn-warning text-light me-2" data-bs-toggle="modal"
|
<v-text-field v-model="person.nikename" label="نام" outlined readonly></v-text-field>
|
||||||
data-bs-target="#notesModal">
|
</v-col>
|
||||||
<span class="badge text-bg-dark me-2">{{ notes.count }}</span>
|
<v-col cols="12" sm="6" md="4">
|
||||||
<i class="fa-regular fa-note-sticky me-1"></i>
|
<v-text-field v-model="person.mobile" label="موبایل" outlined readonly></v-text-field>
|
||||||
<span class="d-none d-sm-inline-block">یادداشتها</span>
|
</v-col>
|
||||||
</button>
|
<v-col cols="12" sm="6" md="4">
|
||||||
<notes :stat="notes" :code="$route.params.id" typeNote="sell" />
|
<v-text-field v-model="person.tel" label="تلفن" outlined readonly></v-text-field>
|
||||||
<!-- Button trigger modal -->
|
</v-col>
|
||||||
<button v-show="parseInt(item.doc.amount) > parseInt(totalRec)" type="button" class="btn btn-sm btn-danger"
|
<v-col cols="12" sm="6" md="3">
|
||||||
@click="recModal.show()">
|
<v-text-field v-model="person.postalcode" label="کد پستی" outlined readonly></v-text-field>
|
||||||
<i class="fas fa-money-bill-1-wave"></i>
|
</v-col>
|
||||||
<span class="d-none d-sm-inline-block">ثبت دریافت</span>
|
<v-col cols="12" sm="12" md="9">
|
||||||
</button>
|
<v-text-field v-model="person.addres" label="آدرس" outlined readonly></v-text-field>
|
||||||
<!-- Modal -->
|
</v-col>
|
||||||
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="rec-modal" tabindex="-1"
|
</v-row>
|
||||||
aria-labelledby="exampleModalLabel1" aria-hidden="true">
|
</v-card-text>
|
||||||
<rec ref="submitPay" :windowsState="PayWindowsState" :person="person.id" :original-doc="item.doc.code"
|
</v-window-item>
|
||||||
:total-amount="parseInt(item.doc.amount) - parseInt(totalRec)">
|
|
||||||
</rec>
|
<!-- تب اطلاعات فاکتور -->
|
||||||
</div>
|
<v-window-item value="invoice-info">
|
||||||
<button type="button" class="btn btn-sm btn-info ms-2" @click="recListModal.show()">
|
<v-card-text>
|
||||||
<i class="fas fa-arrow-alt-circle-down"></i>
|
<v-row>
|
||||||
<span class="d-none d-sm-inline-block">دریافتها</span>
|
<v-col cols="12" sm="6" md="4">
|
||||||
</button>
|
<v-text-field v-model="item.doc.code" label="شماره" outlined readonly></v-text-field>
|
||||||
<!-- Modal -->
|
</v-col>
|
||||||
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="rec-list-modal" tabindex="-1"
|
<v-col cols="12" sm="6" md="4">
|
||||||
aria-hidden="true">
|
<v-text-field v-model="item.doc.date" label="تاریخ" outlined readonly></v-text-field>
|
||||||
<div class="modal-dialog modal-lg">
|
</v-col>
|
||||||
<div class="modal-content">
|
<v-col cols="12" sm="12" md="4">
|
||||||
<div class="modal-header">
|
<v-text-field v-model="item.doc.des" label="شرح" outlined readonly></v-text-field>
|
||||||
<h1 class="modal-title fs-5" id="exampleModalLabel1">
|
</v-col>
|
||||||
<i class="fas fa-arrow-alt-circle-down ms-2"></i>
|
</v-row>
|
||||||
دریافتها
|
|
||||||
</h1>
|
<v-list-subheader>اقلام</v-list-subheader>
|
||||||
<div class="block-options">
|
<v-data-table :headers="mobileHeaders" :items="commoditys" :loading="loading" show-expand class="elevation-1">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<template v-slot:item.sumTotal="{ item }">
|
||||||
</div>
|
{{ $filters.formatNumber(item.sumTotal) }}
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<rec-list ref="recListRef" :windowsState="recListWindowsState" :items="item.relatedDocs"></rec-list>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" ref="btnCloseModalRec" class="btn btn-secondary btn-close-modal"
|
|
||||||
data-bs-dismiss="modal">بازگشت</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Button trigger modal -->
|
|
||||||
<button v-show="bid.shortlinks" type="button" class="btn btn-sm btn-success ms-2" data-bs-toggle="modal"
|
|
||||||
data-bs-target="#exampleModal">
|
|
||||||
<i class="fas fa-share-nodes"></i>
|
|
||||||
<span class="d-none d-sm-inline-block">اشتراک گذاری</span>
|
|
||||||
</button>
|
|
||||||
<!-- Modal -->
|
|
||||||
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="exampleModal" tabindex="-1"
|
|
||||||
aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h1 class="modal-title fs-5" id="exampleModalLabel">
|
|
||||||
<i class="fas fa-share-nodes"></i>
|
|
||||||
اشتراک گذاری
|
|
||||||
</h1>
|
|
||||||
<div class="block-options">
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="input-group mb-2">
|
|
||||||
<div class="input-group-text">
|
|
||||||
<i class="fa fa-paperclip me-2"></i>
|
|
||||||
پیوند فاکتور
|
|
||||||
</div>
|
|
||||||
<input :readonly="true" type="text" class="form-control" v-model="shortlink_url">
|
|
||||||
<button class="btn btn-outline-success" type="button" @click="copyToCliboard()">{{ copy_label
|
|
||||||
}}</button>
|
|
||||||
</div>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-text">
|
|
||||||
<i class="fa fa-message me-2"></i>
|
|
||||||
ارسال پیامک
|
|
||||||
</div>
|
|
||||||
<input type="text" class="form-control" v-model="person.mobile">
|
|
||||||
<button :disabled="loading" class="btn btn-outline-success" type="button" @click="sendSMS()">{{
|
|
||||||
send_message_label }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mt-3">
|
|
||||||
<i class="fas fa-share-nodes me-3"></i>
|
|
||||||
<label>اشتراک گذاری در شبکههای اجتماعی</label>
|
|
||||||
</div>
|
|
||||||
<div class="mt-2">
|
|
||||||
<a target="_blank" :href="'tg://msg?text=' + shortlink_url">
|
|
||||||
<img src="/img/icons/telegram.png" class="m-3" style="max-width: 30px;" />
|
|
||||||
</a>
|
|
||||||
<a target="_blank" :href="'et://msg_url?url=' + shortlink_url">
|
|
||||||
<img src="/img/icons/eitaa.jpeg" class="m-3" style="max-width: 30px;" />
|
|
||||||
</a>
|
|
||||||
<a target="_blank" :href="'https://ble.ir/share/url?url=' + shortlink_url">
|
|
||||||
<img src="/img/icons/bale-logo.png" class="m-3" style="max-width: 30px;" />
|
|
||||||
</a>
|
|
||||||
<a target="_blank" :href="'https://ble.ir/share/url?url=' + shortlink_url">
|
|
||||||
<img src="/img/icons/robika.png" class="m-3" style="max-width: 30px;" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">بازگشت</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- print trigger modal -->
|
|
||||||
<button type="button" class="btn btn-sm btn-primary mx-2" data-bs-toggle="modal" data-bs-target="#printModal">
|
|
||||||
<i class="si si-printer me-1"></i>
|
|
||||||
<span class="d-none d-sm-inline-block">چاپ فاکتور</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="block-content py-2 mt-2">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6 col-md-4">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">شماره</span>
|
|
||||||
<input type="text" :readonly="true" v-model="item.doc.code" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-4">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">تاریخ</span>
|
|
||||||
<input type="text" :readonly="true" v-model="item.doc.date" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-12 col-md-4">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">شرح</span>
|
|
||||||
<input type="text" :readonly="true" v-model="item.doc.des" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<b class="ps-2">خریدار</b>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6 col-md-4">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">نام</span>
|
|
||||||
<input type="text" :readonly="true" v-model="person.nikename" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-4">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">موبایل</span>
|
|
||||||
<input type="text" :readonly="true" v-model="person.mobile" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-4">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">تلفن</span>
|
|
||||||
<input type="text" :readonly="true" v-model="person.tel" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-3">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">کد پستی</span>
|
|
||||||
<input type="text" :readonly="true" v-model="person.postalcode" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-12 col-md-9">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">آدرس</span>
|
|
||||||
<input type="text" :readonly="true" v-model="person.address" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<b class="ps-2">اقلام</b>
|
|
||||||
<EasyDataTable table-class-name="customize-table" :headers="mobileHeaders" :items="commoditys" show-index
|
|
||||||
alternating theme-color="#1d90ff" header-text-direction="center" body-text-direction="center"
|
|
||||||
rowsPerPageMessage="تعداد سطر" emptyMessage="اطلاعاتی برای نمایش وجود ندارد" rowsOfPageSeparatorMessage="از"
|
|
||||||
:loading="loading">
|
|
||||||
<template #item-sumTotal="{ sumTotal }">
|
|
||||||
{{ $filters.formatNumber(sumTotal) }}
|
|
||||||
</template>
|
</template>
|
||||||
<template #item-count="{ count, commodity }">
|
<template v-slot:item.count="{ item }">
|
||||||
{{ count }} {{ commodity.unit }}
|
{{ item.count }} {{ item.commodity.unit }}
|
||||||
</template>
|
</template>
|
||||||
<template #expand="{ tax, discount, des, price }">
|
<template v-slot:expanded-row="{ item }">
|
||||||
<div class="p-1 m-0">
|
<v-list dense>
|
||||||
<ul class="list-group">
|
<v-list-item>
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<v-list-item-title>قیمت واحد</v-list-item-title>
|
||||||
قیمت واحد
|
<v-list-item-subtitle>{{ $filters.formatNumber(item.price) }}</v-list-item-subtitle>
|
||||||
<span class="badge text-bg-primary rounded-pill">
|
</v-list-item>
|
||||||
{{ $filters.formatNumber(price) }}
|
<v-list-item>
|
||||||
</span>
|
<v-list-item-title>تخفیف</v-list-item-title>
|
||||||
</li>
|
<v-list-item-subtitle>{{ $filters.formatNumber(item.discount) }}</v-list-item-subtitle>
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
</v-list-item>
|
||||||
تخفیف
|
<v-list-item>
|
||||||
<span class="badge text-bg-primary rounded-pill">
|
<v-list-item-title>مالیات</v-list-item-title>
|
||||||
{{ $filters.formatNumber(discount) }}
|
<v-list-item-subtitle>{{ $filters.formatNumber(item.tax) }}</v-list-item-subtitle>
|
||||||
</span>
|
</v-list-item>
|
||||||
</li>
|
<v-list-item>
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<v-list-item-title>شرح</v-list-item-title>
|
||||||
مالیات
|
<v-list-item-subtitle>{{ item.des }}</v-list-item-subtitle>
|
||||||
<span class="badge text-bg-primary rounded-pill">
|
</v-list-item>
|
||||||
{{ $filters.formatNumber(tax) }}
|
</v-list>
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
||||||
شرح:
|
|
||||||
{{ des }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</EasyDataTable>
|
</v-data-table>
|
||||||
<div class="row pt-2">
|
|
||||||
<div class="col-sm-6 col-md-4">
|
<v-row class="mt-2">
|
||||||
<div class="input-group input-group-sm mb-3">
|
<v-col cols="12" sm="6" md="4">
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">جمع کل</span>
|
<v-text-field v-model="formattedAmount" label="جمع کل" outlined readonly></v-text-field>
|
||||||
<input type="text" :readonly="true" :value="$filters.formatNumber(item.doc.amount)"
|
</v-col>
|
||||||
class="form-control" aria-describedby="inputGroup-sizing-sm">
|
<v-col cols="12" sm="6" md="4">
|
||||||
</div>
|
<v-text-field v-model="statusText" :color="statusColor" label="وضعیت" outlined readonly></v-text-field>
|
||||||
</div>
|
</v-col>
|
||||||
<div class="col-sm-6 col-md-4">
|
<v-col cols="12" sm="6" md="4">
|
||||||
<div class="input-group input-group-sm mb-3">
|
<v-text-field v-model="profitText" :label="profitLabel" :color="profitColor" outlined readonly></v-text-field>
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">وضعیت</span>
|
</v-col>
|
||||||
<input v-if="parseInt(item.doc.amount) <= parseInt(totalRec)" type="text" :readonly="true"
|
</v-row>
|
||||||
value="تسویه شده" class="form-control text-success" aria-describedby="inputGroup-sizing-sm">
|
|
||||||
<input v-else type="text" :readonly="true" value="تسویه نشده" class="form-control text-danger"
|
<v-row>
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
<v-col cols="12" sm="6" md="4">
|
||||||
</div>
|
<v-text-field v-model="formattedTotalTax" label="مالیات" outlined readonly></v-text-field>
|
||||||
</div>
|
</v-col>
|
||||||
<div class="col-sm-6 col-md-4">
|
<v-col cols="12" sm="6" md="4">
|
||||||
<div v-if="parseInt(item.doc.profit) >= 0" class="input-group input-group-sm mb-3">
|
<v-text-field v-model="formattedDiscountAll" label="تخفیف" outlined readonly></v-text-field>
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">سود فاکتور</span>
|
</v-col>
|
||||||
<input type="text" :readonly="true" :value="$filters.formatNumber(Math.abs(item.doc.profit))"
|
<v-col cols="12" sm="6" md="4">
|
||||||
class="form-control text-success">
|
<v-text-field v-model="formattedTransferCost" label="هزینه حمل و نقل" outlined readonly></v-text-field>
|
||||||
</div>
|
</v-col>
|
||||||
<div v-else class="input-group input-group-sm mb-3">
|
</v-row>
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">زیان فاکتور</span>
|
</v-card-text>
|
||||||
<input type="text" :readonly="true" :value="$filters.formatNumber(Math.abs(item.doc.profit))"
|
</v-window-item>
|
||||||
class="form-control text-danger">
|
|
||||||
</div>
|
<!-- تب دریافتها -->
|
||||||
</div>
|
<v-window-item value="payments">
|
||||||
</div>
|
<v-card-text>
|
||||||
<div class="row">
|
<v-data-table v-if="item.relatedDocs.length" :headers="[
|
||||||
<div class="col-sm-6 col-md-4">
|
{ title: 'مشاهده', key: 'view' },
|
||||||
<div class="input-group input-group-sm mb-3">
|
{ title: 'شماره', key: 'code' },
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">مالیات</span>
|
{ title: 'تاریخ', key: 'date' },
|
||||||
<input type="text" :readonly="true" :value="$filters.formatNumber(totalTax)" class="form-control"
|
{ title: 'مبلغ', key: 'amount' },
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
]" :items="item.relatedDocs">
|
||||||
</div>
|
<template v-slot:item.view="{ item }">
|
||||||
</div>
|
<router-link :to="'/acc/accounting/view/' + item.code">
|
||||||
<div class="col-sm-6 col-md-4">
|
<v-icon color="success">mdi-eye</v-icon>
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">تخفیف</span>
|
|
||||||
<input type="text" :readonly="true" :value="$filters.formatNumber(discountAll)" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-4">
|
|
||||||
<div class="input-group input-group-sm mb-3">
|
|
||||||
<span class="input-group-text" id="inputGroup-sizing-sm">هزینه حمل و نقل</span>
|
|
||||||
<input type="text" :readonly="true" :value="$filters.formatNumber(transferCost)" class="form-control"
|
|
||||||
aria-describedby="inputGroup-sizing-sm">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="block block-rounded">
|
|
||||||
<div class="block-header block-header-default">
|
|
||||||
<h3 class="block-title">دریافتها</h3>
|
|
||||||
<div class="block-options">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="block-content p-0">
|
|
||||||
<table v-if="item.relatedDocs.length != 0"
|
|
||||||
class="table border-0 table-borderless table-striped table-vcenter fs-sm">
|
|
||||||
<thead class="bg-primary text-light">
|
|
||||||
<tr class="text-center">
|
|
||||||
<th>مشاهده</th>
|
|
||||||
<th>شماره</th>
|
|
||||||
<th>تاریخ</th>
|
|
||||||
<th>مبلغ</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="rd in item.relatedDocs" class="text-center">
|
|
||||||
<td>
|
|
||||||
<router-link :to="'/acc/accounting/view/' + rd.code">
|
|
||||||
<span class="text-success fa fa-eye"></span>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</td>
|
</template>
|
||||||
<td class="fw-semibold" style="width: 100px;">
|
<template v-slot:item.amount="{ item }">
|
||||||
{{ rd.code }}
|
{{ $filters.formatNumber(item.amount) }}
|
||||||
</td>
|
</template>
|
||||||
<td class="fw-semibold">
|
</v-data-table>
|
||||||
{{ rd.date }}
|
<v-card-text v-else class="text-center text-danger">
|
||||||
</td>
|
تاکنون سند دریافتی ثبت نشده است
|
||||||
<td class="fw-semibold">
|
</v-card-text>
|
||||||
{{ $filters.formatNumber(rd.amount) }}
|
</v-card-text>
|
||||||
</td>
|
</v-window-item>
|
||||||
</tr>
|
</v-window>
|
||||||
<tr v-if="item.relatedDocs.length == 0" class="text-center">
|
|
||||||
<td colspan="4">
|
|
||||||
سند پرداختی تاکنون ثبت نشده است.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="text-center py-2 text-danger" v-else>
|
|
||||||
<span>تاکنون سند دریافتی ثبت نشده است</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<v-dialog v-model="recDialog" max-width="600">
|
||||||
|
<rec :windows-state="PayWindowsState" :person="person.id" :original-doc="item.doc.code" :total-amount="parseInt(item.doc.amount) - parseInt(totalRec)" />
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
<v-dialog v-model="recListDialog" max-width="800">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
<v-icon left>mdi-arrow-down-circle</v-icon>
|
||||||
|
دریافتها
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<rec-list :windows-state="recListWindowsState" :items="item.relatedDocs" />
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn color="secondary" @click="recListDialog = false">بازگشت</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
table {
|
/* استایلها */
|
||||||
font-size: small;
|
|
||||||
border: 1px solid gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-header {
|
|
||||||
background-color: lightgray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c-print {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media print {
|
|
||||||
@page {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding-top: 72px;
|
|
||||||
padding-bottom: 72px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
Loading…
Reference in a new issue