diff --git a/hesabixCore/config/packages/security.yaml b/hesabixCore/config/packages/security.yaml index 73ab524..fa3f15c 100644 --- a/hesabixCore/config/packages/security.yaml +++ b/hesabixCore/config/packages/security.yaml @@ -8,7 +8,6 @@ security: app_user_provider: entity: class: App\Entity\User - property: mobile firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ diff --git a/hesabixCore/src/Controller/SellController.php b/hesabixCore/src/Controller/SellController.php index 32053a8..53de691 100644 --- a/hesabixCore/src/Controller/SellController.php +++ b/hesabixCore/src/Controller/SellController.php @@ -1164,6 +1164,7 @@ class SellController extends AbstractController } } $entityManager->flush(); + // سیاست جدید: در ویرایش، شماره فاکتور تغییر نمی‌کند (نادیده گرفتن هر ورودی مربوط به شماره) } else { // ایجاد فاکتور جدید $doc = new HesabdariDoc(); @@ -1173,7 +1174,36 @@ class SellController extends AbstractController $doc->setType('sell'); $doc->setSubmitter($this->getUser()); $doc->setMoney($acc['money']); - $doc->setCode($provider->getAccountingCode($acc['bid'], 'accounting')); + // انتخاب شماره فاکتور بر اساس حالت شماره گذاری + $numberingMode = $params['numberingMode'] ?? 'auto'; + if ($numberingMode === 'custom') { + $customNumber = isset($params['customNumber']) ? trim((string)$params['customNumber']) : ''; + if ($customNumber === '') { + return $this->json([ + 'result' => 0, + 'message' => 'شماره سفارشی ارسال نشده است' + ], 400); + } + if (!preg_match('/^[A-Za-z0-9_-]{1,30}$/', $customNumber)) { + return $this->json([ + 'result' => 0, + 'message' => 'فرمت شماره فاکتور نامعتبر است' + ], 400); + } + $exist = $entityManager->getRepository(HesabdariDoc::class)->findOneBy([ + 'bid' => $acc['bid'], + 'code' => $customNumber + ]); + if ($exist) { + return $this->json([ + 'result' => 0, + 'message' => 'این شماره فاکتور قبلاً استفاده شده است' + ], 400); + } + $doc->setCode($customNumber); + } else { + $doc->setCode($provider->getAccountingCode($acc['bid'], 'accounting')); + } if ($TwoStepApproval) { $doc->setIsPreview(true); $doc->setIsApproved(false); diff --git a/hesabixCore/src/Repository/UserRepository.php b/hesabixCore/src/Repository/UserRepository.php index d1165a7..cad33eb 100644 --- a/hesabixCore/src/Repository/UserRepository.php +++ b/hesabixCore/src/Repository/UserRepository.php @@ -8,6 +8,7 @@ use Doctrine\Persistence\ManagerRegistry; use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; +use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface; /** * @extends ServiceEntityRepository @@ -17,13 +18,53 @@ use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; * @method User[] findAll() * @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface +class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface, UserLoaderInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, User::class); } + public function loadUserByIdentifier(string $identifier): ?User + { + $identifier = trim($identifier); + + $qb = $this->createQueryBuilder('u'); + + if (str_contains($identifier, '@')) { + $email = mb_strtolower($identifier); + return $qb + ->andWhere('LOWER(u.email) = :email') + ->setParameter('email', $email) + ->getQuery() + ->getOneOrNullResult(); + } + + $mobile = $this->normalizeMobile($identifier); + $emailFromIdentifier = mb_strtolower($identifier); + + return $qb + ->andWhere('u.mobile = :mobile OR LOWER(u.email) = :email') + ->setParameter('mobile', $mobile) + ->setParameter('email', $emailFromIdentifier) + ->getQuery() + ->getOneOrNullResult(); + } + + private function normalizeMobile(string $value): string + { + $value = $this->convertPersianToEnglish($value); + $value = preg_replace('/\s+/', '', $value ?? ''); + return (string) $value; + } + + private function convertPersianToEnglish(string $input): string + { + $persianNumbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; + $englishNumbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + return str_replace($persianNumbers, $englishNumbers, $input); + } + public function save(User $entity, bool $flush = false): void { $this->getEntityManager()->persist($entity); diff --git a/webUI/src/i18n/en_lang.ts b/webUI/src/i18n/en_lang.ts index e7b9c1b..5df5745 100755 --- a/webUI/src/i18n/en_lang.ts +++ b/webUI/src/i18n/en_lang.ts @@ -46,6 +46,8 @@ const en_lang = { password_sended: "کلمه عبور جدید به شماره تلفن شما ارسال شد.", mobile_placeholder:"مثلا 09121234567", mobile:"Mobile number", + email_or_mobile:"Email or Mobile", + email_or_mobile_placeholder:"Enter your email or mobile number", send_new_password: "Send new password", editNumber: "Edit Number", resendCodeLabel: "Send Again", diff --git a/webUI/src/i18n/fa_lang.ts b/webUI/src/i18n/fa_lang.ts index 16acd25..3855b94 100755 --- a/webUI/src/i18n/fa_lang.ts +++ b/webUI/src/i18n/fa_lang.ts @@ -683,6 +683,8 @@ const fa_lang = { password_sended: "کلمه عبور جدید به شماره تلفن شما ارسال شد.", mobile_placeholder: "مثلا 09121234567", mobile: "تلفن همراه", + email_or_mobile: "ایمیل یا شماره موبایل", + email_or_mobile_placeholder: "ایمیل یا شماره موبایل خود را وارد کنید", send_new_password: "ارسال کلمه عبور جدید", editNumber: "ویرایش شماره", resendCodeLabel: "ارسال مجدد", diff --git a/webUI/src/views/acc/bank/card.vue b/webUI/src/views/acc/bank/card.vue index 1ecc408..04975c6 100755 --- a/webUI/src/views/acc/bank/card.vue +++ b/webUI/src/views/acc/bank/card.vue @@ -305,8 +305,6 @@ export default { ).then((response) => { this.items = response.data; this.items.forEach((item) => { - item.bs = this.$filters.formatNumber(item.bs) - item.bd = this.$filters.formatNumber(item.bd) item.accounts = []; // Initialize accounts array }) this.loadCounterpartAccounts(id); diff --git a/webUI/src/views/acc/sell/mod.vue b/webUI/src/views/acc/sell/mod.vue index 1b4a03b..135633e 100755 --- a/webUI/src/views/acc/sell/mod.vue +++ b/webUI/src/views/acc/sell/mod.vue @@ -41,6 +41,40 @@ + + + + روش شماره‌گذاری + + + + + + + + + + + + +