diff --git a/hesabixCore/migrations/Version20250824071413.php b/hesabixCore/migrations/Version20250824071413.php
new file mode 100644
index 0000000..5ba4e31
--- /dev/null
+++ b/hesabixCore/migrations/Version20250824071413.php
@@ -0,0 +1,35 @@
+addSql(<<<'SQL'
+ ALTER TABLE person ADD payment_id VARCHAR(255) DEFAULT NULL
+ SQL);
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->addSql(<<<'SQL'
+ ALTER TABLE person DROP payment_id
+ SQL);
+ }
+}
diff --git a/hesabixCore/src/Cog/PersonService.php b/hesabixCore/src/Cog/PersonService.php
index 1137a6d..7d3400a 100644
--- a/hesabixCore/src/Cog/PersonService.php
+++ b/hesabixCore/src/Cog/PersonService.php
@@ -95,7 +95,7 @@ class PersonService
if (!empty($search) || $search === '0') {
$search = trim($search);
- $queryBuilder->andWhere('p.nikename LIKE :search OR p.name LIKE :search OR p.code LIKE :search OR p.mobile LIKE :search')
+ $queryBuilder->andWhere('p.nikename LIKE :search OR p.name LIKE :search OR p.code LIKE :search OR p.mobile LIKE :search OR p.paymentId LIKE :search')
->setParameter('search', "%$search%");
}
@@ -288,6 +288,22 @@ class PersonService
if (isset($params['shenasemeli'])) $person->setShenasemeli($params['shenasemeli']);
if (isset($params['company'])) $person->setCompany($params['company']);
if (isset($params['tags'])) $person->setTags($params['tags']);
+
+ // بررسی منحصر به فرد بودن شناسه پرداخت در کسب و کار
+ if (isset($params['paymentId']) && !empty(trim($params['paymentId']))) {
+ $existingPerson = $em->getRepository(\App\Entity\Person::class)->findOneBy([
+ 'paymentId' => trim($params['paymentId']),
+ 'bid' => $acc['bid']
+ ]);
+
+ // اگر شخص دیگری با همین شناسه پرداخت وجود دارد و این شخص فعلی نیست
+ if ($existingPerson && $existingPerson->getId() !== $person->getId()) {
+ return ['result' => -4, 'error' => 'شناسه پرداخت تکراری است'];
+ }
+ $person->setPaymentId(trim($params['paymentId']));
+ } else {
+ $person->setPaymentId(null);
+ }
if (array_key_exists('prelabel', $params)) {
if ($params['prelabel'] != '') {
diff --git a/hesabixCore/src/Controller/PersonsController.php b/hesabixCore/src/Controller/PersonsController.php
index 4102ef2..9753829 100644
--- a/hesabixCore/src/Controller/PersonsController.php
+++ b/hesabixCore/src/Controller/PersonsController.php
@@ -295,7 +295,8 @@ class PersonsController extends AbstractController
'id' => $person->getId(),
'nikename' => $person->getNikename(),
'code' => $person->getCode(),
- 'mobile' => $person->getMobile()
+ 'mobile' => $person->getMobile(),
+ 'paymentId' => $person->getPaymentId()
];
$rows = $entityManager->getRepository(HesabdariRow::class)->findBy([
'person' => $person,
@@ -344,7 +345,8 @@ class PersonsController extends AbstractController
'id' => $person->getId(),
'nikename' => $person->getNikename(),
'code' => $person->getCode(),
- 'mobile' => $person->getMobile()
+ 'mobile' => $person->getMobile(),
+ 'paymentId' => $person->getPaymentId()
];
$rows = $entityManager->getRepository(HesabdariRow::class)->findBy([
'person' => $person,
diff --git a/hesabixCore/src/Entity/Person.php b/hesabixCore/src/Entity/Person.php
index 13e26f0..1fccfbd 100644
--- a/hesabixCore/src/Entity/Person.php
+++ b/hesabixCore/src/Entity/Person.php
@@ -161,6 +161,8 @@ class Person
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $tags = null;
+ #[ORM\Column(length: 255, nullable: true)]
+ private ?string $paymentId = null;
public function __construct()
@@ -916,5 +918,16 @@ class Person
return $this;
}
+ public function getPaymentId(): ?string
+ {
+ return $this->paymentId;
+ }
+
+ public function setPaymentId(?string $paymentId): self
+ {
+ $this->paymentId = $paymentId;
+ return $this;
+ }
+
}
diff --git a/hesabixCore/src/Repository/PersonRepository.php b/hesabixCore/src/Repository/PersonRepository.php
index 246dd9b..76d32a3 100644
--- a/hesabixCore/src/Repository/PersonRepository.php
+++ b/hesabixCore/src/Repository/PersonRepository.php
@@ -47,7 +47,7 @@ class PersonRepository extends ServiceEntityRepository
{
return $this->createQueryBuilder('p')
->where('p.bid = :val')
- ->andWhere("p.nikename LIKE :search OR p.mobile LIKE :search")
+ ->andWhere("p.nikename LIKE :search OR p.mobile LIKE :search OR p.paymentId LIKE :search")
->setParameter('val', $bid)
->setParameter('search', '%' . $search . '%')
->setMaxResults($maxResults)
diff --git a/hesabixCore/src/Service/Explore.php b/hesabixCore/src/Service/Explore.php
index 964c452..44fea77 100644
--- a/hesabixCore/src/Service/Explore.php
+++ b/hesabixCore/src/Service/Explore.php
@@ -354,6 +354,7 @@ class Explore
'address' => $person->getAddress(),
'prelabel' => null,
'tags' => $person->getTags(),
+ 'paymentId' => $person->getPaymentId(),
'requireTwoStep' => $person->getBid() ? $person->getBid()->isRequireTwoStepApproval() : false,
];
if ($person->getPrelabel()) {
diff --git a/webUI/src/components/PersonInfo.vue b/webUI/src/components/PersonInfo.vue
index ce73dd2..3d6e93c 100644
--- a/webUI/src/components/PersonInfo.vue
+++ b/webUI/src/components/PersonInfo.vue
@@ -59,6 +59,10 @@
استان:
{{ person.ostan }}
+
+ شناسه پرداخت:
+ {{ person.paymentId }}
+
diff --git a/webUI/src/components/forms/Hpersonsearch.vue b/webUI/src/components/forms/Hpersonsearch.vue
index 174c5e2..8f35b23 100755
--- a/webUI/src/components/forms/Hpersonsearch.vue
+++ b/webUI/src/components/forms/Hpersonsearch.vue
@@ -56,6 +56,12 @@
{{ formatBalance(item.balance) }}
+
+
+ mdi-credit-card-outline
+ شناسه پرداخت: {{ item.paymentId }}
+
+
@@ -156,6 +162,12 @@
label="توضیحات"
>
+
+
+
{
if (item.bank == '') {
canSubmit = false;
- Swal.fire({
- text: 'بخش حسابهای بانکی به درستی تکمیل نشده است.لطفا موارد الزامی را وارد کنید.',
- icon: 'error',
- confirmButtonText: 'قبول'
- });
+ this.showSnackbar('بخش حسابهای بانکی به درستی تکمیل نشده است.لطفا موارد الزامی را وارد کنید.', 'error');
}
});
if (canSubmit) {
@@ -135,21 +137,22 @@ export default defineComponent({
axios.post('/api/person/mod/' + this.person.code, this.person).then((response) => {
this.loading = false;
if (response.data.result == 2) {
- Swal.fire({
- text: 'قبلا ثبت شده است.',
- icon: 'error',
- confirmButtonText: 'قبول'
- });
+ this.showSnackbar('قبلا ثبت شده است.', 'error');
+ }
+ else if (response.data.result == -4) {
+ this.showSnackbar(response.data.error || 'شناسه پرداخت تکراری است.', 'error');
}
else {
- Swal.fire({
- text: 'مشخصات شخص ثبت شد.',
- icon: 'success',
- confirmButtonText: 'قبول'
- }).then(() => {
- this.person = this.personPattern
- this.dialog = false;
- });
+ this.showSnackbar('مشخصات شخص ثبت شد.', 'success');
+ this.person = this.personPattern;
+ this.dialog = false;
+ }
+ }).catch((error) => {
+ this.loading = false;
+ if (error.response && error.response.data && error.response.data.result === -4) {
+ this.showSnackbar(error.response.data.error || 'شناسه پرداخت تکراری است.', 'error');
+ } else {
+ this.showSnackbar('خطا در ثبت شخص.', 'error');
}
})
}
@@ -256,6 +259,12 @@ export default defineComponent({
+
@@ -445,6 +454,16 @@ export default defineComponent({
+
+
+
+ {{ snackbar.text }}
+
+
+ بستن
+
+
+
\ No newline at end of file
diff --git a/webUI/src/views/acc/persons/card.vue b/webUI/src/views/acc/persons/card.vue
index 8518352..c684892 100755
--- a/webUI/src/views/acc/persons/card.vue
+++ b/webUI/src/views/acc/persons/card.vue
@@ -151,6 +151,13 @@
dense
/>
+
+
+
@@ -229,6 +236,8 @@
selectedPerson.address || '-' }}
{{ $t('pages.person.description') }}: {{
selectedPerson.des || '-' }}
+ شناسه پرداخت: {{
+ selectedPerson.paymentId || '-' }}
@@ -352,7 +361,7 @@ export default {
tel: '',
address: '',
des: '',
-
+ paymentId: '',
},
debounceTimeout: null, // برای مدیریت debounce
headers: [
@@ -437,7 +446,7 @@ export default {
tel: this.selectedPerson.tel || '',
address: this.selectedPerson.address || '',
des: this.selectedPerson.des || '',
-
+ paymentId: this.selectedPerson.paymentId || '',
};
const rowsResponse = await axios.post('/api/accounting/rows/search', { type: 'person', id });
@@ -463,12 +472,18 @@ export default {
this.editPersonDialog = false;
// بروزرسانی اطلاعات شخص
await this.loadPerson(this.selectedPerson.code);
+ } else if (response.data.result === -4) {
+ this.snackbar = { show: true, text: response.data.error || 'شناسه پرداخت تکراری است', color: 'error' };
} else {
this.snackbar = { show: true, text: 'خطا در بروزرسانی اطلاعات شخص', color: 'error' };
}
} catch (error) {
console.error('Save person error:', error);
- this.snackbar = { show: true, text: 'خطا در بروزرسانی اطلاعات شخص', color: 'error' };
+ if (error.response && error.response.data && error.response.data.result === -4) {
+ this.snackbar = { show: true, text: error.response.data.error || 'شناسه پرداخت تکراری است', color: 'error' };
+ } else {
+ this.snackbar = { show: true, text: 'خطا در بروزرسانی اطلاعات شخص', color: 'error' };
+ }
} finally {
this.saveLoading = false;
}
diff --git a/webUI/src/views/acc/persons/insert.vue b/webUI/src/views/acc/persons/insert.vue
index f3dbdbb..5d6274d 100755
--- a/webUI/src/views/acc/persons/insert.vue
+++ b/webUI/src/views/acc/persons/insert.vue
@@ -65,6 +65,10 @@
+
+
+
@@ -289,6 +293,7 @@ export default {
accounts: [],
prelabel: ref(null),
speedAccess: false,
+ paymentId: '',
},
snackbar: {
@@ -418,6 +423,12 @@ export default {
icon: 'error',
confirmButtonText: this.$t('dialog.confirm')
});
+ } else if (response.data && response.data.result === -4) {
+ Swal.fire({
+ text: response.data.error || 'شناسه پرداخت تکراری است',
+ icon: 'error',
+ confirmButtonText: this.$t('dialog.confirm')
+ });
} else {
Swal.fire({
text: this.$t('pages.person.saved'),
@@ -429,11 +440,19 @@ export default {
}
} catch (error) {
this.loading = false;
- Swal.fire({
- text: this.$t('pages.person.save_error') + error.message,
- icon: 'error',
- confirmButtonText: this.$t('dialog.confirm')
- });
+ if (error.response && error.response.data && error.response.data.result === -4) {
+ Swal.fire({
+ text: error.response.data.error || 'شناسه پرداخت تکراری است',
+ icon: 'error',
+ confirmButtonText: this.$t('dialog.confirm')
+ });
+ } else {
+ Swal.fire({
+ text: this.$t('pages.person.save_error') + error.message,
+ icon: 'error',
+ confirmButtonText: this.$t('dialog.confirm')
+ });
+ }
}
}
},
diff --git a/webUI/src/views/acc/persons/list.vue b/webUI/src/views/acc/persons/list.vue
index c8fb4e0..50c7dc7 100755
--- a/webUI/src/views/acc/persons/list.vue
+++ b/webUI/src/views/acc/persons/list.vue
@@ -255,6 +255,7 @@ const allHeaders = ref([
{ title: 'ایمیل', value: 'email', sortable: true, visible: true, align: 'center' },
{ title: 'وب سایت', value: 'website', sortable: true, visible: true, align: 'center' },
{ title: 'فکس', value: 'fax', sortable: true, visible: true, align: 'center' },
+ { title: 'شناسه پرداخت', value: 'paymentId', sortable: true, visible: true, align: 'center' },
]);
// توابع کمکی