diff --git a/hesabixCore/src/Controller/AdminController.php b/hesabixCore/src/Controller/AdminController.php
index dc092b5..ffef7b9 100644
--- a/hesabixCore/src/Controller/AdminController.php
+++ b/hesabixCore/src/Controller/AdminController.php
@@ -448,6 +448,7 @@ class AdminController extends AbstractController
$resp['footer'] = $item->getFooter();
$resp['activeGateway'] = $registryMGR->get('system', key: 'activeGateway');
$resp['parsianGatewayAPI'] = $registryMGR->get('system', key: 'parsianGatewayAPI');
+ $resp['paypingKey'] = $registryMGR->get('system', key: 'paypingKey');
return $this->json($resp);
}
@@ -470,6 +471,7 @@ class AdminController extends AbstractController
$item->setFooter($params['footer']);
$registryMGR->update('system', 'activeGateway', $params['activeGateway']);
$registryMGR->update('system', 'parsianGatewayAPI', $params['parsianGatewayAPI']);
+ $registryMGR->update('system', 'paypingKey', $params['paypingKey']);
$entityManager->persist($item);
$entityManager->flush();
return $this->json(['result' => 1]);
diff --git a/hesabixCore/src/Controller/PersonsController.php b/hesabixCore/src/Controller/PersonsController.php
index fd1775e..ccacc90 100644
--- a/hesabixCore/src/Controller/PersonsController.php
+++ b/hesabixCore/src/Controller/PersonsController.php
@@ -124,16 +124,23 @@ class PersonsController extends AbstractController
//check exist before
if (!$person) {
$person = new Person();
- $code = $provider->getAccountingCode($acc['bid'], 'person');
- $exist = $entityManager->getRepository(Person::class)->findOneBy([
- 'code' => $code
- ]);
- while ($exist) {
+ $maxAttempts = 10; // حداکثر تعداد تلاش برای تولید کد جدید
+ $code = null;
+
+ for ($i = 0; $i < $maxAttempts; $i++) {
$code = $provider->getAccountingCode($acc['bid'], 'person');
$exist = $entityManager->getRepository(Person::class)->findOneBy([
'code' => $code
]);
+ if (!$exist) {
+ break;
+ }
}
+
+ if ($code === null) {
+ throw new \Exception('نمیتوان کد جدیدی برای شخص تولید کرد');
+ }
+
$person->setCode($code);
}
@@ -270,16 +277,23 @@ class PersonsController extends AbstractController
//check exist before
if (!$person) {
$person = new Person();
- $code = $provider->getAccountingCode($acc['bid'], 'person');
- $exist = $entityManager->getRepository(Person::class)->findOneBy([
- 'code' => $code
- ]);
- while ($exist) {
+ $maxAttempts = 10; // حداکثر تعداد تلاش برای تولید کد جدید
+ $code = null;
+
+ for ($i = 0; $i < $maxAttempts; $i++) {
$code = $provider->getAccountingCode($acc['bid'], 'person');
$exist = $entityManager->getRepository(Person::class)->findOneBy([
'code' => $code
]);
+ if (!$exist) {
+ break;
+ }
}
+
+ if ($code === null) {
+ throw new \Exception('نمیتوان کد جدیدی برای شخص تولید کرد');
+ }
+
$person->setCode($code);
}
@@ -520,7 +534,7 @@ class PersonsController extends AbstractController
// جستوجو (بهبود دادهشده)
if (!empty($search) || $search === '0') { // برای اطمینان از کار با "0" یا خالی
$search = trim($search); // حذف فضای خالی اضافی
- $queryBuilder->andWhere('p.nikename LIKE :search OR p.name LIKE :search OR p.code LIKE :search')
+ $queryBuilder->andWhere('p.nikename LIKE :search OR p.name LIKE :search OR p.code LIKE :search OR p.mobile LIKE :search')
->setParameter('search', "%$search%");
}
@@ -1567,16 +1581,23 @@ class PersonsController extends AbstractController
//check exist before
if (!$person) {
$person = new Person();
- $code = $provider->getAccountingCode($acc['bid'], 'person');
- $exist = $entityManager->getRepository(Person::class)->findOneBy([
- 'code' => $code
- ]);
- while ($exist) {
+ $maxAttempts = 10; // حداکثر تعداد تلاش برای تولید کد جدید
+ $code = null;
+
+ for ($i = 0; $i < $maxAttempts; $i++) {
$code = $provider->getAccountingCode($acc['bid'], 'person');
$exist = $entityManager->getRepository(Person::class)->findOneBy([
'code' => $code
]);
+ if (!$exist) {
+ break;
+ }
}
+
+ if ($code === null) {
+ throw new \Exception('نمیتوان کد جدیدی برای شخص تولید کرد');
+ }
+
$person->setCode($code);
$person->setNikename($item[0]);
$person->setBid($acc['bid']);
diff --git a/hesabixCore/src/Controller/Plugins/PlugGhestaController.php b/hesabixCore/src/Controller/Plugins/PlugGhestaController.php
index 8387e52..d873db6 100644
--- a/hesabixCore/src/Controller/Plugins/PlugGhestaController.php
+++ b/hesabixCore/src/Controller/Plugins/PlugGhestaController.php
@@ -13,6 +13,10 @@ use App\Entity\HesabdariDoc;
use App\Entity\Person;
use App\Service\Access;
use App\Service\Provider;
+use App\Service\Printers;
+use App\Entity\PrintOptions;
+use App\Service\Log;
+use App\Entity\Business;
class PlugGhestaController extends AbstractController
{
@@ -416,4 +420,72 @@ class PlugGhestaController extends AbstractController
], 500);
}
}
+
+ #[Route('/api/plugins/ghesta/print', name: 'plugin_ghesta_print', methods: ['POST'])]
+ public function plugin_ghesta_print(Printers $printers, Provider $provider, Request $request, Access $access, Log $log, EntityManagerInterface $entityManager): JsonResponse
+ {
+ $acc = $access->hasRole('plugGhestaManager');
+ if (!$acc)
+ throw $this->createAccessDeniedException();
+
+ $params = json_decode($request->getContent(), true);
+ $params['pdf'] = $params['pdf'] ?? true;
+
+ // دریافت تنظیمات پیشفرض از PrintOptions
+ $printSettings = $entityManager->getRepository(PrintOptions::class)->findOneBy(['bid' => $acc['bid']]);
+
+ // تنظیم مقادیر پیشفرض از تنظیمات ذخیره شده
+ $defaultOptions = [
+ 'note' => $printSettings ? $printSettings->isSellNote() : true,
+ 'bidInfo' => $printSettings ? $printSettings->isSellBidInfo() : true,
+ 'paper' => $printSettings ? $printSettings->getSellPaper() : 'A4-L',
+ 'businessStamp' => $printSettings ? $printSettings->isSellBusinessStamp() : true
+ ];
+
+ // اولویت با پارامترهای ارسالی است
+ $printOptions = array_merge($defaultOptions, $params['printOptions'] ?? []);
+
+ $doc = $entityManager->getRepository(PlugGhestaDoc::class)->findOneBy([
+ 'id' => $params['id'],
+ 'bid' => $acc['bid']
+ ]);
+
+ if (!$doc)
+ throw $this->createNotFoundException();
+
+ $pdfPid = 0;
+ if ($params['pdf'] == true) {
+ $note = '';
+ if ($printSettings) {
+ $note = $printSettings->getSellNoteString();
+ }
+
+ // دریافت اطلاعات کسب و کار
+ $business = $entityManager->getRepository(Business::class)->find($acc['bid']);
+
+ $pdfPid = $provider->createPrint(
+ $acc['bid'],
+ $this->getUser(),
+ $this->renderView('pdf/plugins/ghesta/report.html.twig', [
+ 'bid' => $business,
+ 'doc' => $doc,
+ 'items' => array_map(function($item) {
+ return [
+ 'date' => $item->getDate(),
+ 'amount' => $item->getAmount(),
+ 'num' => $item->getNum(),
+ 'hesabdariDoc' => $item->getHesabdariDoc()
+ ];
+ }, $doc->getPlugGhestaItems()->toArray()),
+ 'person' => $doc->getPerson(),
+ 'printOptions' => $printOptions,
+ 'note' => $note
+ ]),
+ false,
+ $printOptions['paper']
+ );
+ }
+
+ return $this->json(['id' => $pdfPid]);
+ }
}
\ No newline at end of file
diff --git a/hesabixCore/src/Controller/ReportController.php b/hesabixCore/src/Controller/ReportController.php
index 6c1faaf..dc91f22 100644
--- a/hesabixCore/src/Controller/ReportController.php
+++ b/hesabixCore/src/Controller/ReportController.php
@@ -24,6 +24,7 @@ use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use App\Entity\PrintOptions;
class ReportController extends AbstractController
{
@@ -581,4 +582,116 @@ class ReportController extends AbstractController
return $this->json(['error' => 'An error occurred: ' . $e->getMessage()], 500);
}
}
+
+ #[Route('/api/report/person/buysell/export/pdf', name: 'app_report_person_buysell_export_pdf')]
+ public function app_report_person_buysell_export_pdf(Provider $provider, Access $access, Request $request, EntityManagerInterface $entityManagerInterface): BinaryFileResponse|JsonResponse|StreamedResponse
+ {
+ $acc = $access->hasRole('report');
+ if (!$acc)
+ throw $this->createAccessDeniedException();
+ $params = [];
+ if ($content = $request->getContent()) {
+ $params = json_decode($content, true);
+ }
+
+ $items = [];
+ foreach ($params['items'] as $param) {
+ $prs = $entityManagerInterface->getRepository(HesabdariRow::class)->findOneBy([
+ 'id' => $param['rowId'],
+ 'bid' => $acc['bid']
+ ]);
+ if ($prs)
+ $items[] = $prs;
+ }
+
+ // دریافت اطلاعات شخص از اولین آیتم
+ $person = null;
+ if (count($items) > 0) {
+ foreach ($items[0]->getDoc()->getHesabdariRows() as $row) {
+ if ($row->getPerson()) {
+ $person = $row->getPerson();
+ break;
+ }
+ }
+ }
+
+ $response = [];
+ foreach ($items as $item) {
+ $temp = [
+ 'id' => $item->getCommodity()->getId(),
+ 'code' => $item->getCommodity()->getCode(),
+ 'khadamat' => $item->getCommodity()->isKhadamat(),
+ 'name' => $item->getCommodity()->getName(),
+ 'unit' => $item->getCommodity()->getUnit()->getName(),
+ 'count' => $item->getCommdityCount(),
+ 'date' => $item->getDoc()->getDate(),
+ 'docCode' => $item->getDoc()->getCode(),
+ 'type' => $item->getDoc()->getType()
+ ];
+ if ($item->getDoc()->getType() == 'buy') {
+ $temp['priceAll'] = $item->getBd();
+ } elseif ($item->getDoc()->getType() == 'sell') {
+ $temp['priceAll'] = $item->getBs();
+ }
+ if ($temp['count'] != 0) {
+ $temp['priceOne'] = $temp['priceAll'] / $temp['count'];
+ $temp['priceAll'] = number_format($temp['priceAll']);
+ $temp['priceOne'] = number_format($temp['priceOne']);
+ $temp['count'] = number_format($temp['count']);
+ $response[] = $temp;
+ }
+ }
+
+ // اضافه کردن شماره ردیف به دادهها
+ $responseWithRow = [];
+ foreach ($response as $index => $item) {
+ $responseWithRow[] = [
+ 'row' => $index + 1,
+ 'code' => $item['code'],
+ 'name' => $item['name'],
+ 'unit' => $item['unit'],
+ 'count' => $item['count'],
+ 'priceOne' => $item['priceOne'],
+ 'priceAll' => $item['priceAll'],
+ 'date' => $item['date'],
+ 'docCode' => $item['docCode'],
+ 'type' => $item['type'],
+ 'khadamat' => $item['khadamat']
+ ];
+ }
+
+ // دریافت تنظیمات چاپ
+ $printSettings = $entityManagerInterface->getRepository(PrintOptions::class)->findOneBy(['bid' => $acc['bid']]);
+
+ // تنظیم مقادیر پیشفرض از تنظیمات ذخیره شده
+ $defaultOptions = [
+ 'note' => $printSettings ? $printSettings->isSellNote() : true,
+ 'bidInfo' => $printSettings ? $printSettings->isSellBidInfo() : true,
+ 'taxInfo' => $printSettings ? $printSettings->isSellTaxInfo() : true,
+ 'discountInfo' => $printSettings ? $printSettings->isSellDiscountInfo() : true,
+ 'pays' => $printSettings ? $printSettings->isSellPays() : true,
+ 'paper' => $printSettings ? $printSettings->getSellPaper() : 'A4-L',
+ 'invoiceIndex' => $printSettings ? $printSettings->isSellInvoiceIndex() : true,
+ 'businessStamp' => $printSettings ? $printSettings->isSellBusinessStamp() : true
+ ];
+
+ // اولویت با پارامترهای ارسالی است
+ $printOptions = array_merge($defaultOptions, $params['printOptions'] ?? []);
+
+ $pdfPid = $provider->createPrint(
+ $acc['bid'],
+ $this->getUser(),
+ $this->renderView('pdf/printers/buysell_report.html.twig', [
+ 'bid' => $acc['bid'],
+ 'items' => $responseWithRow,
+ 'printOptions' => $printOptions,
+ 'note' => $printSettings ? $printSettings->getSellNoteString() : '',
+ 'person' => $person
+ ]),
+ false,
+ $printOptions['paper']
+ );
+
+ return $this->json(['id' => $pdfPid]);
+ }
}
\ No newline at end of file
diff --git a/hesabixCore/src/Controller/SellController.php b/hesabixCore/src/Controller/SellController.php
index 51a6596..1b28b7b 100644
--- a/hesabixCore/src/Controller/SellController.php
+++ b/hesabixCore/src/Controller/SellController.php
@@ -747,27 +747,53 @@ class SellController extends AbstractController
$this->renderView('pdf/printers/sell.html.twig', [
'bid' => $acc['bid'],
'doc' => $doc,
- 'rows' => $doc->getHesabdariRows(),
+ 'rows' => array_map(function($row) {
+ return [
+ 'commodity' => $row->getCommodity(),
+ 'commodityCount' => $row->getCommdityCount(),
+ 'des' => $row->getDes(),
+ 'bs' => $row->getBs(),
+ 'tax' => $row->getTax(),
+ 'discount' => $row->getDiscount(),
+ 'showPercentDiscount' => $row->getDiscountType() === 'percent',
+ 'discountPercent' => $row->getDiscountPercent()
+ ];
+ }, $doc->getHesabdariRows()->toArray()),
'person' => $person,
'printInvoice' => $params['printers'],
'discount' => $discount,
'transfer' => $transfer,
'printOptions' => $printOptions,
- 'note' => $note
+ 'note' => $note,
+ 'showPercentDiscount' => $doc->getDiscountType() === 'percent',
+ 'discountPercent' => $doc->getDiscountPercent()
]),
false,
$printOptions['paper']
);
}
if ($params['posPrint'] == true) {
-
$pid = $provider->createPrint(
$acc['bid'],
$this->getUser(),
$this->renderView('pdf/posPrinters/justSell.html.twig', [
'bid' => $acc['bid'],
'doc' => $doc,
- 'rows' => $doc->getHesabdariRows(),
+ 'rows' => array_map(function($row) {
+ return [
+ 'commodity' => $row->getCommodity(),
+ 'commodityCount' => $row->getCommdityCount(),
+ 'des' => $row->getDes(),
+ 'bs' => $row->getBs(),
+ 'tax' => $row->getTax(),
+ 'discount' => $row->getDiscount(),
+ 'showPercentDiscount' => $row->getDiscountType() === 'percent',
+ 'discountPercent' => $row->getDiscountPercent()
+ ];
+ }, $doc->getHesabdariRows()->toArray()),
+ 'discount' => $discount,
+ 'showPercentDiscount' => $doc->getDiscountType() === 'percent',
+ 'discountPercent' => $doc->getDiscountPercent()
]),
false
);
diff --git a/hesabixCore/src/Service/PayMGR.php b/hesabixCore/src/Service/PayMGR.php
index 8933f04..a0acacc 100644
--- a/hesabixCore/src/Service/PayMGR.php
+++ b/hesabixCore/src/Service/PayMGR.php
@@ -79,6 +79,58 @@ class PayMGR
}
}
}
+ } elseif ($activeGateway == 'payping') {
+ $data = array(
+ 'amount' => $price,
+ 'returnUrl' => $callback_url,
+ 'description' => $des,
+ 'clientRefId' => $orderID
+ );
+
+ $ch = curl_init('https://api.payping.ir/v2/pay');
+ curl_setopt_array($ch, array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_ENCODING => "",
+ CURLOPT_MAXREDIRS => 10,
+ CURLOPT_TIMEOUT => 45,
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+ CURLOPT_CUSTOMREQUEST => "POST",
+ CURLOPT_POSTFIELDS => json_encode($data),
+ CURLOPT_HTTPHEADER => array(
+ "accept: application/json",
+ "authorization: Bearer " . $this->registry->get('system', 'paypingKey'),
+ "cache-control: no-cache",
+ "content-type: application/json",
+ ),
+ ));
+
+ $response = curl_exec($ch);
+ $err = curl_error($ch);
+ $header = curl_getinfo($ch);
+ curl_close($ch);
+
+ if ($err) {
+ $res['message'] = 'خطا در ارتباط با پیپینگ: ' . $err;
+ return $res;
+ }
+
+ if ($header['http_code'] == 200) {
+ $response = json_decode($response, true);
+ if (isset($response['code'])) {
+ $res['code'] = 100;
+ $res['Success'] = true;
+ $res['gate'] = 'payping';
+ $res['message'] = 'OK';
+ $res['authkey'] = $response['code'];
+ $res['targetURL'] = 'https://api.payping.ir/v2/pay/gotoipg/' . $response['code'];
+ } else {
+ $res['message'] = 'خطا در دریافت کد پرداخت از پیپینگ';
+ }
+ } elseif ($header['http_code'] == 400) {
+ $res['message'] = 'خطا در درخواست پرداخت: ' . $response;
+ } else {
+ $res['message'] = 'خطا در ارتباط با پیپینگ. کد خطا: ' . $header['http_code'];
+ }
} elseif ($activeGateway == 'pec') {
ini_set("soap.wsdl_cache_enabled", "0");
$url = "https://pec.shaparak.ir/NewIPGServices/Sale/SaleService.asmx?WSDL";
@@ -150,6 +202,53 @@ class PayMGR
}
}
}
+ } elseif ($activeGateway == 'payping') {
+ $refid = $request->get('refid');
+ if (!$refid) {
+ return $res;
+ }
+
+ $data = array(
+ 'amount' => $price,
+ 'refId' => $refid
+ );
+
+ $ch = curl_init('https://api.payping.ir/v2/pay/verify');
+ curl_setopt_array($ch, array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_ENCODING => "",
+ CURLOPT_MAXREDIRS => 10,
+ CURLOPT_TIMEOUT => 45,
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+ CURLOPT_CUSTOMREQUEST => "POST",
+ CURLOPT_POSTFIELDS => json_encode($data),
+ CURLOPT_HTTPHEADER => array(
+ "accept: application/json",
+ "authorization: Bearer " . $this->registry->get('system', 'paypingKey'),
+ "cache-control: no-cache",
+ "content-type: application/json",
+ ),
+ ));
+
+ $response = curl_exec($ch);
+ $err = curl_error($ch);
+ $header = curl_getinfo($ch);
+ curl_close($ch);
+
+ if ($err) {
+ return $res;
+ }
+
+ if ($header['http_code'] == 200) {
+ $response = json_decode($response, true);
+ if (isset($refid) && $refid != '') {
+ $res['Success'] = true;
+ $res['status'] = 100;
+ $res['refID'] = $refid;
+ $res['card_pan'] = ''; // PayPing این اطلاعات را برنمیگرداند
+ return $res;
+ }
+ }
} elseif ($activeGateway == 'pec') {
$confirmUrl = 'https://pec.shaparak.ir/NewIPGServices/Confirm/ConfirmService.asmx?WSDL';
$params = array(
diff --git a/hesabixCore/src/Service/pdfMGR.php b/hesabixCore/src/Service/pdfMGR.php
index 680c639..788c515 100644
--- a/hesabixCore/src/Service/pdfMGR.php
+++ b/hesabixCore/src/Service/pdfMGR.php
@@ -55,6 +55,12 @@ class pdfMGR
],
'default_font' => 'vazirmatn',
'tempDir' => $tempDir,
+ 'margin_left' => 5,
+ 'margin_right' => 5,
+ 'margin_top' => 5,
+ 'margin_bottom' => 5,
+ 'margin_header' => 2,
+ 'margin_footer' => 2,
'autoArabic' => true,
]);
diff --git a/hesabixCore/templates/pdf/plugins/ghesta/report.html.twig b/hesabixCore/templates/pdf/plugins/ghesta/report.html.twig
new file mode 100644
index 0000000..65ccc9c
--- /dev/null
+++ b/hesabixCore/templates/pdf/plugins/ghesta/report.html.twig
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+ {{ bid.name }}
+ گزارش اقساط
+ |
+
+
+ شماره فاکتور:
+ {{ doc.mainDoc.code }}
+ |
+
+
+
+
+
+
+
+ خریدار
+
+
+
+
+
+
+ نام:
+ {% if person.prelabel is not null %}{{ person.prelabel.label }}{% endif %}
+ {{ person.nikename }}
+
+ |
+
+
+ شناسه ملی:
+ {{ person.shenasemeli }}
+
+ |
+
+
+ شماره ثبت:
+ {{ person.sabt }}
+
+ |
+
+
+ شماره اقتصادی:
+ {{ person.codeeghtesadi }}
+
+ |
+
+
+ تلفن / نمابر:
+ {{ person.tel }}
+
+ |
+
+
+
+
+ کد پستی:
+ {{ person.postalcode }}
+
+ |
+
+
+ آدرس:
+ استان {{ person.ostan }}، شهر {{ person.shahr }}، {{ person.address }}
+
+ |
+
+
+
+
+
+
+
+ اطلاعات اقساط
+
+
+
+
+
+
+ تعداد اقساط:
+ {{ doc.count }}
+
+ |
+
+
+ درصد سود:
+ {{ doc.profitPercent }}%
+
+ |
+
+
+ مبلغ سود:
+ {{ doc.profitAmount|number_format }} ریال
+
+ |
+
+
+ نوع سود:
+ {% if doc.profitType == 'yearly' %}
+ سالانه
+ {% elseif doc.profitType == 'monthly' %}
+ ماهانه
+ {% else %}
+ روزانه
+ {% endif %}
+
+ |
+
+
+ جریمه روزانه:
+ {{ doc.daysPay }}%
+
+ |
+
+
+
+
+
+
+
+
+
+ شماره قسط |
+ تاریخ |
+ مبلغ |
+ وضعیت |
+
+
+
+ {% for item in items %}
+
+ {{ item.num }} |
+ {{ item.date|date('Y/m/d') }} |
+ {{ item.amount|number_format }} ریال |
+
+ {% if item.hesabdariDoc %}
+ پرداخت شده ({{ item.hesabdariDoc.code }})
+ {% else %}
+ پرداخت نشده
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+
+
+ {% if printOptions.note and note %}
+
+
+
+
+
+ توضیحات:
+ {{ note|nl2br }}
+ |
+
+
+
+
+ {% endif %}
+
+
+
+
+
+
+ مهر و امضا خریدار
+ |
+
+ مهر و امضا فروشنده:
+
+ {% if printOptions.businessStamp %}
+
+ {% endif %}
+ |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hesabixCore/templates/pdf/posPrinters/justSell.html.twig b/hesabixCore/templates/pdf/posPrinters/justSell.html.twig
index ec1590b..612d906 100644
--- a/hesabixCore/templates/pdf/posPrinters/justSell.html.twig
+++ b/hesabixCore/templates/pdf/posPrinters/justSell.html.twig
@@ -6,7 +6,7 @@
body {
margin: 5px;
padding: 0;
- font-size: 100%;
+ font-size: 11px;
}
table {
@@ -19,10 +19,12 @@
th,
td {
border: 1px solid black !important;
+ font-size: 11px;
}
h1 {
text-align: center;
vertical-align: middle;
+ font-size: 14px;
}
#logo {
@@ -60,7 +62,7 @@
}
.items .heading {
- font-size: 12.5px;
+ font-size: 11px;
text-transform: uppercase;
border-top: 1px solid black;
margin-bottom: 4px;
@@ -75,7 +77,7 @@
}
.items td {
- font-size: 12px;
+ font-size: 11px;
text-align: center;
vertical-align: bottom;
}
@@ -89,7 +91,7 @@
text-align: right !important;
}
.total {
- font-size: 13px;
+ font-size: 11px;
border-top: 1px dashed black !important;
border-bottom: 1px dashed black !important;
}
@@ -110,7 +112,7 @@
}
section,
footer {
- font-size: 12px;
+ font-size: 11px;
}
tbody,
thead,
@@ -150,6 +152,7 @@
کالا |
تعداد |
فی |
+ قبل تخفیف |
جمع |
@@ -159,8 +162,29 @@
{% if row.commodity != null %}
{{row.commodity.name}} |
- {{row.commdityCount}} |
- {{(row.bs / row.commdityCount) | number_format}} |
+ {{row.commodityCount}} |
+
+ {% if row.commodityCount > 0 %}
+ {% if row.showPercentDiscount %}
+ {% set originalPrice = row.bs / (1 - (row.discountPercent / 100)) %}
+ {% set unitPrice = originalPrice / row.commodityCount %}
+ {% else %}
+ {% set originalPrice = row.bs + row.discount %}
+ {% set unitPrice = originalPrice / row.commodityCount %}
+ {% endif %}
+ {{ unitPrice|round|number_format }}
+ {% else %}
+ 0
+ {% endif %}
+ |
+
+ {% if row.showPercentDiscount %}
+ {% set originalPrice = row.bs / (1 - (row.discountPercent / 100)) %}
+ {{ originalPrice|round|number_format }}
+ {% else %}
+ {{ (row.bs + row.discount)|number_format }}
+ {% endif %}
+ |
{{row.bs | number_format}} |
{% endif %}
@@ -169,6 +193,19 @@
جمع فاکتور |
{{doc.amount | number_format}} |
+ {% if discount > 0 %}
+
+ تخفیف |
+
+ {% if showPercentDiscount %}
+ {{ discountPercent }}%
+ ({{ (doc.amount * discountPercent / 100)|round|number_format }})
+ {% else %}
+ {{ discount | number_format }}
+ {% endif %}
+ |
+
+ {% endif %}
diff --git a/hesabixCore/templates/pdf/printers/buy.html.twig b/hesabixCore/templates/pdf/printers/buy.html.twig
index a4d7fd3..64f977a 100644
--- a/hesabixCore/templates/pdf/printers/buy.html.twig
+++ b/hesabixCore/templates/pdf/printers/buy.html.twig
@@ -276,7 +276,7 @@
{{transfer | number_format}}
- مبلغ کل بدون تخفیف:
+ جمع بدون تخفیف:
{{ (doc.amount + discount) | number_format}}
diff --git a/hesabixCore/templates/pdf/printers/buysell_report.html.twig b/hesabixCore/templates/pdf/printers/buysell_report.html.twig
new file mode 100644
index 0000000..7387152
--- /dev/null
+++ b/hesabixCore/templates/pdf/printers/buysell_report.html.twig
@@ -0,0 +1,187 @@
+
+
+
+
+ گزارش خرید و فروش
+
+
+
+
+
+
+
+
+
+
+ {% if printOptions.invoiceIndex %}
+
+ {% endif %}
+ |
+
+ {{ bid.legalName }}
+ گزارش خرید و فروش
+ |
+
+
+ تاریخ چاپ:
+ {{ "now"|date("Y/m/d") }}
+ |
+
+
+
+
+
+ {% if printOptions.bidInfo %}
+
+
+ اطلاعات شخص
+
+
+
+
+
+
+ نام:
+ {% if person.prelabel is not null %}{{ person.prelabel.label }}{% endif %}
+ {{ person.nikename }}
+
+ |
+
+
+ شناسه ملی:
+ {{ person.shenasemeli }}
+
+ |
+
+
+ شماره ثبت:
+ {{ person.sabt }}
+
+ |
+
+
+ شماره اقتصادی:
+ {{ person.codeeghtesadi }}
+
+ |
+
+
+ تلفن / نمابر:
+ {{ person.tel }}
+
+ |
+
+
+
+
+ کد پستی:
+ {{ person.postalcode }}
+
+ |
+
+
+ آدرس:
+ استان {{ person.ostan }}، شهر {{ person.shahr }}، {{ person.address }}
+
+ |
+
+
+
+
+ {% endif %}
+
+
+
+
+
+ ردیف |
+ کد کالا |
+ نام کالا |
+ واحد |
+ تعداد |
+ قیمت واحد |
+ قیمت کل |
+ تاریخ |
+ شماره سند |
+ نوع سند |
+ نوع |
+
+
+
+ {% for item in items %}
+
+ {{ item.row }} |
+ {{ item.code }} |
+ {{ item.name }} |
+ {{ item.unit }} |
+ {{ item.count }} |
+ {{ item.priceOne }} |
+ {{ item.priceAll }} |
+ {{ item.date }} |
+ {{ item.docCode }} |
+
+ {% if item.type == 'buy' %}
+ خرید
+ {% elseif item.type == 'sell' %}
+ فروش
+ {% elseif item.type == 'rfbuy' %}
+ برگشت از خرید
+ {% elseif item.type == 'rfsell' %}
+ برگشت از فروش
+ {% endif %}
+ |
+
+ {% if item.khadamat %}
+ خدمات
+ {% else %}
+ کالا
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+ مهر و امضا
+ {% if printOptions.businessStamp %}
+
+ {% endif %}
+ |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hesabixCore/templates/pdf/printers/rfbuy.html.twig b/hesabixCore/templates/pdf/printers/rfbuy.html.twig
index 57561b7..1c3e2f0 100644
--- a/hesabixCore/templates/pdf/printers/rfbuy.html.twig
+++ b/hesabixCore/templates/pdf/printers/rfbuy.html.twig
@@ -276,7 +276,7 @@
{{transfer | number_format}}
- مبلغ کل بدون تخفیف:
+ جمع بدون تخفیف:
{{ (doc.amount + discount) | number_format}}
diff --git a/hesabixCore/templates/pdf/printers/rfsell.html.twig b/hesabixCore/templates/pdf/printers/rfsell.html.twig
index 8612f38..832abdc 100644
--- a/hesabixCore/templates/pdf/printers/rfsell.html.twig
+++ b/hesabixCore/templates/pdf/printers/rfsell.html.twig
@@ -276,7 +276,7 @@
{{transfer | number_format}}
- مبلغ کل بدون تخفیف:
+ جمع بدون تخفیف:
{{ (doc.amount + discount) | number_format}}
diff --git a/hesabixCore/templates/pdf/printers/sell.html.twig b/hesabixCore/templates/pdf/printers/sell.html.twig
index 05bee97..1d2b56b 100644
--- a/hesabixCore/templates/pdf/printers/sell.html.twig
+++ b/hesabixCore/templates/pdf/printers/sell.html.twig
@@ -15,6 +15,16 @@
}
.item {
height: 30px;
+ font-size: 11px;
+ }
+ h3 {
+ font-size: 14px;
+ }
+ h4 {
+ font-size: 12px;
+ }
+ p {
+ font-size: 11px;
}
@@ -191,6 +201,7 @@
مبلغ واحد |
{% if printOptions.discountInfo %}
تخفیف |
+ قبل تخفیف |
{% endif %}
{% if printOptions.taxInfo %}
مالیات |
@@ -213,18 +224,40 @@
{{ item.commodity.name }}
{{ item.des }} |
- {{ item.commdityCount }}
+ {{ item.commodityCount }}
{{ item.commodity.unit.name }}
|
- {% if item.commdityCount > 0 %}
- {{ ((item.bs|number_format(0, '.', '') - item.tax|number_format(0, '.', '') + item.discount|number_format(0, '.', '')) / item.commdityCount) | number_format }}
+ {% if item.commodityCount > 0 %}
+ {% if item.showPercentDiscount %}
+ {% set originalPrice = item.bs / (1 - (item.discountPercent / 100)) %}
+ {% set unitPrice = originalPrice / item.commodityCount %}
+ {% else %}
+ {% set originalPrice = item.bs + item.discount %}
+ {% set unitPrice = originalPrice / item.commodityCount %}
+ {% endif %}
+ {{ unitPrice|round|number_format }}
{% else %}
0
{% endif %}
|
{% if printOptions.discountInfo %}
- {{ item.discount | number_format }} |
+
+ {% if item.showPercentDiscount %}
+ {{ item.discountPercent }}%
+ ({{ (item.bs * item.commodityCount * item.discountPercent / 100)|round|number_format }})
+ {% else %}
+ {{ item.discount|number_format }}
+ {% endif %}
+ |
+
+ {% if item.showPercentDiscount %}
+ {% set originalPrice = item.bs / (1 - (item.discountPercent / 100)) %}
+ {{ originalPrice|round|number_format }}
+ {% else %}
+ {{ (item.bs + item.discount)|number_format }}
+ {% endif %}
+ |
{% endif %}
{% if printOptions.taxInfo %}
{{ item.tax | number_format}} |
@@ -285,7 +318,7 @@
{% if doc.amount != (doc.amount + discount) %}
- مبلغ کل بدون تخفیف:
+ جمع بدون تخفیف:
{{ (doc.amount + discount) | number_format}}
{% endif %}
diff --git a/webUI/src/i18n/fa_lang.ts b/webUI/src/i18n/fa_lang.ts
index 41010a8..e86d377 100644
--- a/webUI/src/i18n/fa_lang.ts
+++ b/webUI/src/i18n/fa_lang.ts
@@ -286,6 +286,7 @@ const fa_lang = {
fetch_data_error: "خطا در گرفتن داده از {url}"
},
dialog: {
+ person_with_det_report: 'گزارش تفضیلی اشخاص',
change_password_label: 'تغییر کلمه عبور',
download: 'دانلود',
delete_group: 'حذف گروهی',
@@ -793,6 +794,7 @@ const fa_lang = {
keywords: "کلیدواژهها با کاما (,) از هم جدا شوند",
zarinpal_api: "کد API زرینپال",
parsian_api: "کد API درگاه پارسیان",
+ payping_api: "کد API درگاه پیپینگ",
scripts: "اسکریپتها",
footer_scripts: "اسکریپتهای فوتر سایت(مثلا اسکریپت شمارنده گوگل و ...)",
site_footer: "فوتر سایت با پشتیبانی از HTML",
diff --git a/webUI/src/router/index.ts b/webUI/src/router/index.ts
index a7d859f..b48744b 100644
--- a/webUI/src/router/index.ts
+++ b/webUI/src/router/index.ts
@@ -298,6 +298,12 @@ const router = createRouter({
component: () =>
import('../views/acc/reports/persons/buysellByPerson.vue'),
},
+ {
+ path: 'reports/persons/withdet',
+ name: 'person_withdet',
+ component: () =>
+ import('../views/acc/reports/persons/withdet.vue'),
+ },
{
path: 'costs/list',
name: 'costs_list',
diff --git a/webUI/src/views/acc/plugins/ghesta/mod.vue b/webUI/src/views/acc/plugins/ghesta/mod.vue
index beb06d0..34d4619 100644
--- a/webUI/src/views/acc/plugins/ghesta/mod.vue
+++ b/webUI/src/views/acc/plugins/ghesta/mod.vue
@@ -933,13 +933,6 @@ export default {
this.isCalculating = true;
this.loading = true;
- // اگر در حالت ویرایش هستیم و اقساط قبلاً محاسبه شدهاند، از آنها استفاده کن
- if (this.$route.params.id && this.installments.length > 0) {
- this.isCalculating = false;
- this.loading = false;
- return;
- }
-
const totalAmount = this.remainingAmount;
const prepayment = Number(this.installmentData.prepayment) || 0;
const remainingAmount = totalAmount - prepayment;
@@ -1121,6 +1114,13 @@ export default {
},
immediate: true
},
+ 'installmentData.count': {
+ handler(newVal) {
+ if (newVal && this.installmentData.calculationType === 'count') {
+ this.calculateInstallments();
+ }
+ }
+ },
'installmentData.interestRate': {
handler(newVal, oldVal) {
if (newVal && !oldVal) {
@@ -1181,4 +1181,91 @@ export default {
font-weight: 600;
background-color: rgb(var(--v-theme-surface));
}
+
+:deep(.vpd-main) {
+ position: fixed !important;
+ z-index: 999999 !important;
+ top: 50% !important;
+ left: 50% !important;
+ transform: translate(-50%, -50%) !important;
+ pointer-events: auto !important;
+}
+
+:deep(.vpd-wrapper) {
+ position: fixed !important;
+ z-index: 999999 !important;
+ top: 50% !important;
+ left: 50% !important;
+ transform: translate(-50%, -50%) !important;
+ pointer-events: auto !important;
+}
+
+:deep(.vpd-container) {
+ position: fixed !important;
+ z-index: 999999 !important;
+ top: 50% !important;
+ left: 50% !important;
+ transform: translate(-50%, -50%) !important;
+ pointer-events: auto !important;
+}
+
+:deep(.vpd-content) {
+ position: fixed !important;
+ z-index: 999999 !important;
+ top: 50% !important;
+ left: 50% !important;
+ transform: translate(-50%, -50%) !important;
+ pointer-events: auto !important;
+}
+
+:deep(.vpd-overlay) {
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ right: 0 !important;
+ bottom: 0 !important;
+ background: rgba(0, 0, 0, 0.5) !important;
+ z-index: 999998 !important;
+ pointer-events: auto !important;
+}
+
+:deep(.v-application) {
+ position: relative !important;
+}
+
+:deep(.v-application--wrap) {
+ position: relative !important;
+}
+
+:deep(.v-main) {
+ position: relative !important;
+}
+
+:deep(.v-main__wrap) {
+ position: relative !important;
+}
+
+:deep(.v-container) {
+ position: relative !important;
+}
+
+:deep(.v-row) {
+ position: relative !important;
+}
+
+:deep(.v-col) {
+ position: relative !important;
+}
+
+:deep(.v-card) {
+ position: relative !important;
+}
+
+:deep(.v-field) {
+ position: relative !important;
+}
+
+:deep(.v-field__input) {
+ position: relative !important;
+}
\ No newline at end of file
diff --git a/webUI/src/views/acc/plugins/ghesta/view.vue b/webUI/src/views/acc/plugins/ghesta/view.vue
index e42cf55..568ba51 100644
--- a/webUI/src/views/acc/plugins/ghesta/view.vue
+++ b/webUI/src/views/acc/plugins/ghesta/view.vue
@@ -8,6 +8,11 @@
+
+
+
+
+
@@ -640,6 +645,40 @@ export default {
} finally {
this.loading = false
}
+ },
+ async printReport() {
+ try {
+ this.loading = true;
+ const response = await axios.post('/api/plugins/ghesta/print', {
+ id: this.$route.params.id,
+ pdf: true
+ });
+
+ if (response.data && response.data.id) {
+ // دریافت فایل PDF
+ const pdfResponse = await axios({
+ method: 'get',
+ url: '/front/print/' + response.data.id,
+ responseType: 'arraybuffer'
+ });
+
+ // ایجاد لینک دانلود
+ const fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
+ const fileLink = document.createElement('a');
+ fileLink.href = fileURL;
+ fileLink.setAttribute('download', `گزارش اقساط ${this.invoice.code}.pdf`);
+ document.body.appendChild(fileLink);
+ fileLink.click();
+ } else {
+ throw new Error('خطا در دریافت شناسه چاپ');
+ }
+ } catch (error) {
+ console.error('خطا در چاپ گزارش:', error);
+ this.error = 'خطا در چاپ گزارش';
+ this.errorDialog = true;
+ } finally {
+ this.loading = false;
+ }
}
},
created() {
diff --git a/webUI/src/views/acc/reports/persons/buysellByPerson.vue b/webUI/src/views/acc/reports/persons/buysellByPerson.vue
index 253b5b6..fbe29cf 100644
--- a/webUI/src/views/acc/reports/persons/buysellByPerson.vue
+++ b/webUI/src/views/acc/reports/persons/buysellByPerson.vue
@@ -10,6 +10,29 @@
+
+
+
+
+
+
+
+
+ {{ $t('dialog.export_pdf') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -276,7 +299,7 @@ export default {
var fileLink = document.createElement('a');
fileLink.href = fileURL;
- fileLink.setAttribute('download', 'buysell-report-list.xlsx');
+ fileLink.setAttribute('download', `${this.selectedPerson.nikename} - گزارش خرید و فروش.xlsx`);
document.body.appendChild(fileLink);
fileLink.click();
})
@@ -301,18 +324,44 @@ export default {
var fileLink = document.createElement('a');
fileLink.href = fileURL;
- fileLink.setAttribute('download', 'buysell-report-list.xlsx');
+ fileLink.setAttribute('download', `${this.selectedPerson.nikename} - گزارش خرید و فروش.xlsx`);
document.body.appendChild(fileLink);
fileLink.click();
})
}
}
},
- print(AllItems = true) {
+ pdfOutput(AllItems = true) {
if (AllItems) {
- axios.post('/api/person/list/print').then((response) => {
- this.printID = response.data.id;
- window.open(this.$API_URL + '/front/print/' + this.printID, '_blank', 'noreferrer');
+ axios({
+ method: 'post',
+ url: '/api/report/person/buysell/export/pdf',
+ data: {
+ items: this.items,
+ printOptions: {
+ paper: 'A4-L',
+ bidInfo: true,
+ taxInfo: true,
+ discountInfo: true,
+ pays: true,
+ invoiceIndex: true,
+ businessStamp: true
+ }
+ }
+ }).then((response) => {
+ axios({
+ method: 'get',
+ url: '/front/print/' + response.data.id,
+ responseType: 'arraybuffer'
+ }).then((pdfResponse) => {
+ var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
+ var fileLink = document.createElement('a');
+
+ fileLink.href = fileURL;
+ fileLink.setAttribute('download', `${this.selectedPerson.nikename} - گزارش خرید و فروش.pdf`);
+ document.body.appendChild(fileLink);
+ fileLink.click();
+ });
})
}
else {
@@ -324,9 +373,35 @@ export default {
});
}
else {
- axios.post('/api/person/list/print', { items: this.itemsSelected }).then((response) => {
- this.printID = response.data.id;
- window.open(this.$API_URL + '/front/print/' + this.printID, '_blank', 'noreferrer');
+ axios({
+ method: 'post',
+ url: '/api/report/person/buysell/export/pdf',
+ data: {
+ items: this.itemsSelected,
+ printOptions: {
+ paper: 'A4-L',
+ bidInfo: true,
+ taxInfo: true,
+ discountInfo: true,
+ pays: true,
+ invoiceIndex: true,
+ businessStamp: true
+ }
+ }
+ }).then((response) => {
+ axios({
+ method: 'get',
+ url: '/front/print/' + response.data.id,
+ responseType: 'arraybuffer'
+ }).then((pdfResponse) => {
+ var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
+ var fileLink = document.createElement('a');
+
+ fileLink.href = fileURL;
+ fileLink.setAttribute('download', `${this.selectedPerson.nikename} - گزارش خرید و فروش.pdf`);
+ document.body.appendChild(fileLink);
+ fileLink.click();
+ });
})
}
}
diff --git a/webUI/src/views/acc/reports/persons/withdet.vue b/webUI/src/views/acc/reports/persons/withdet.vue
new file mode 100644
index 0000000..864906b
--- /dev/null
+++ b/webUI/src/views/acc/reports/persons/withdet.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webUI/src/views/acc/reports/reports.vue b/webUI/src/views/acc/reports/reports.vue
index 5bc0241..ff27c6e 100644
--- a/webUI/src/views/acc/reports/reports.vue
+++ b/webUI/src/views/acc/reports/reports.vue
@@ -1,79 +1,96 @@
-
+
گزارشات
-
+
-
-
-
- mdi-account
+
+
+
+ mdi-account
اشخاص
-
-
- {{ item.text }}
-
+
+
+
+
+ mdi-chevron-left
+ {{ item.text }}
+
+
+
-
-
-
- mdi-bank
+
+
+
+ mdi-bank
بانکداری
-
-
- {{ item.text }}
+
+
+
+ mdi-chevron-left
+ {{ item.text }}
+
-
-
-
- mdi-cog
+
+
+
+ mdi-cog
گزارشات پایه
-
-
- تاریخچه رویدادها
+
+
+
+ mdi-chevron-left
+ تاریخچه رویدادها
+
-
-
-
- mdi-package-variant
+
+
+
+ mdi-package-variant
کالا و خدمات
-
-
- خرید و فروش به تفکیک کالا
+
+
+
+ mdi-chevron-left
+ خرید و فروش به تفکیک کالا
+
-
-
-
- mdi-format-list-bulleted
+
+
+
+ mdi-format-list-bulleted
حسابداری
-
-
- {{ item.text }}
+
+
+
+ mdi-chevron-left
+ {{ item.text }}
+
@@ -91,10 +108,11 @@ export default {
return {
plugins: [],
personReports: [
- { text: 'کارت حساب', to: '/acc/persons/card/view/' },
- { text: 'بدهکاران', to: '/acc/reports/persons/debtors' },
- { text: 'بستانکاران', to: '/acc/reports/persons/depositors' },
- { text: 'خرید و فروش های اشخاص', to: '/acc/reports/persons/buysell' }
+ { text: 'کارت حساب', to: '/acc/persons/card/view/', showIf: null },
+ { text: 'بدهکاران', to: '/acc/reports/persons/debtors', showIf: null },
+ { text: 'بستانکاران', to: '/acc/reports/persons/depositors', showIf: null },
+ { text: 'خرید و فروش های اشخاص', to: '/acc/reports/persons/buysell', showIf: null },
+ { text: 'گزارش تفضیلی اشخاص', to: '/acc/reports/persons/withdet', showIf: 'accpro' }
],
bankReports: [
{ text: 'گردش حساب بانک', to: '/acc/banks/card/view/' },
@@ -124,10 +142,81 @@ export default {
\ No newline at end of file
diff --git a/webUI/src/views/acc/sell/list.vue b/webUI/src/views/acc/sell/list.vue
index 9c1ac79..d615d22 100644
--- a/webUI/src/views/acc/sell/list.vue
+++ b/webUI/src/views/acc/sell/list.vue
@@ -570,11 +570,43 @@ export default defineComponent({
'pdf': pdf,
'printers': cloudePrinters,
'printOptions': this.printOptions
- }).then((response) => {
- this.loading = false;
- window.open(this.$API_URL + '/front/print/' + response.data.id, '_blank', 'noreferrer');
- }).catch(() => {
+ }).then(async (response) => {
+ try {
+ if (response.data && response.data.id) {
+ // دریافت فایل PDF
+ const pdfResponse = await axios({
+ method: 'get',
+ url: '/front/print/' + response.data.id,
+ responseType: 'arraybuffer'
+ });
+
+ // ایجاد لینک دانلود
+ var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
+ var fileLink = document.createElement('a');
+ fileLink.href = fileURL;
+ fileLink.setAttribute('download', `فاکتور فروش ${this.printOptions.selectedPrintCode}.pdf`);
+ document.body.appendChild(fileLink);
+ fileLink.click();
+ } else {
+ throw new Error('خطا در دریافت شناسه چاپ');
+ }
+ } catch (error) {
+ console.error('خطا در دریافت فایل PDF:', error);
+ Swal.fire({
+ text: 'خطا در دریافت فایل PDF',
+ icon: 'error',
+ confirmButtonText: 'قبول'
+ });
+ } finally {
+ this.loading = false;
+ }
+ }).catch((error) => {
this.loading = false;
+ Swal.fire({
+ text: 'خطا در ایجاد نسخه PDF',
+ icon: 'error',
+ confirmButtonText: 'قبول'
+ });
});
},
deleteItem(code) {
diff --git a/webUI/src/views/acc/sell/mod.vue b/webUI/src/views/acc/sell/mod.vue
index 517416f..a6753e9 100644
--- a/webUI/src/views/acc/sell/mod.vue
+++ b/webUI/src/views/acc/sell/mod.vue
@@ -1019,8 +1019,20 @@ export default {
});
if (printResponse.data && printResponse.data.id) {
- // باز کردن PDF در پنجره جدید
- window.open(this.$API_URL + '/front/print/' + printResponse.data.id, '_blank', 'noreferrer');
+ // دریافت فایل PDF
+ const pdfResponse = await axios({
+ method: 'get',
+ url: '/front/print/' + printResponse.data.id,
+ responseType: 'arraybuffer'
+ });
+
+ // ایجاد لینک دانلود
+ var fileURL = window.URL.createObjectURL(new Blob([pdfResponse.data]));
+ var fileLink = document.createElement('a');
+ fileLink.href = fileURL;
+ fileLink.setAttribute('download', `فاکتور فروش ${response.data.data.code}.pdf`);
+ document.body.appendChild(fileLink);
+ fileLink.click();
} else {
throw new Error('خطا در دریافت شناسه چاپ');
}
diff --git a/webUI/src/views/acc/smspanel/smspanel.vue b/webUI/src/views/acc/smspanel/smspanel.vue
index a798ed5..3f103df 100644
--- a/webUI/src/views/acc/smspanel/smspanel.vue
+++ b/webUI/src/views/acc/smspanel/smspanel.vue
@@ -1,22 +1,26 @@
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+ {{ snackbar.text }}
+
+
+ بستن
+
+
+
+
mdi-plus-circle
@@ -40,27 +44,78 @@
- مبلغ اعتبار
-
- به مبالغ زیر ۱۰ درصد مالیات بر ارزش افزوده اضافه میگردد.
+
+
+
+
+
+
+
+ اطلاعات مالی:
+
+
+ - به مبالغ انتخاب شده ۱۰ درصد مالیات بر ارزش افزوده اضافه میگردد.
+ - اعتبار خریداری شده بلافاصله به حساب شما اضافه خواهد شد.
+ - این اعتبار صرفاً برای استفاده از سرویس پیامک کوتاه قابل استفاده است و برای سایر خدمات قابل استفاده نمیباشد.
+
+
-
-
-
-
-
-
+
+
+
+
+
+ {{ amount.label }}
+
+
+ {{ formatPrice(amount.value) }} تومان
+
+
+ با احتساب مالیات: {{ formatPrice(amount.value * 1.1) }} تومان
+
+
+
+
+
+
+
+ مبلغ دلخواه
+
+
+ با احتساب مالیات: {{ formatPrice(Number(customAmount) * 1.1) }} تومان
+
+
+
+
+
+
+
+
+
+
+ mdi-credit-card-outline
+ پرداخت آنلاین
+
-
- mdi-credit-card-outline
- پرداخت آنلاین
-
@@ -69,55 +124,29 @@
در نظر داشته باشید در صورت اتمام اعتبار سرویس پیامک کسب و کار شما، این تنظیمات نادیده گرفته میشود.
- پیامکهای ارسالی به شماره ثبت شده در بخش اشخاص (تلفن همراه) ارسال میشود.
- - در صورت ثبت نکردن شماره تلفن در بخش اشخاص پیامک ارسال نمی شود و هزینه ای نیز از حساب شما کسر نخواهد شد.
+ - در صورت ثبت نکردن شماره تلفن در بخش اشخاص پیامک ارسال نمی شود و هزینه ای نیز از حساب شما کسر نخواهد
+ شد.
-
-
+
+
-
-
+
+
-
-
+
+
{{ item.status === 0 ? 'پرداخت نشده' : 'پرداخت شده' }}
@@ -127,23 +156,11 @@
-
-
+
+
@@ -164,7 +181,20 @@ export default defineComponent({
sendAfterBuy: false,
sendAfterBuyToUser: false,
},
+ snackbar: {
+ show: false,
+ text: '',
+ color: 'error'
+ },
smsCharge: 100000,
+ customAmount: '',
+ isCustomAmount: false,
+ chargeAmounts: [
+ { label: '۱۰ هزار تومان', value: 10000 },
+ { label: '۵۰ هزار تومان', value: 50000 },
+ { label: '۱۰۰ هزار تومان', value: 100000 },
+ { label: '۲۰۰ هزار تومان', value: 200000 }
+ ],
searchValue: '',
loading: true,
items: [],
@@ -177,7 +207,7 @@ export default defineComponent({
paysitems: [] as Array<{ dateSubmit: string; price: number; des: string; status: number }>,
paysheaders: [
{ title: "تاریخ", key: "dateSubmit" },
- { title: "مبلغ (ریال)", key: "price" },
+ { title: "مبلغ (تومان)", key: "price" },
{ title: "توضیحات", key: "des" },
{ title: "وضعیت", key: "status" },
]
@@ -205,8 +235,21 @@ export default defineComponent({
.then((response) => {
if (response.data.Success === true) {
window.location.href = response.data.targetURL;
+ } else {
+ this.snackbar.text = response.data.message || 'خطا در ایجاد درخواست پرداخت';
+ this.snackbar.color = 'error';
+ this.snackbar.show = true;
}
})
+ .catch((error) => {
+ this.snackbar.text = 'خطا در ارتباط با سرور';
+ this.snackbar.color = 'error';
+ this.snackbar.show = true;
+ console.error('Error:', error);
+ })
+ .finally(() => {
+ this.loading = false;
+ });
},
saveSettings(settings: { sendAfterSell: boolean; sendAfterSellPayOnline: boolean; sendAfterBuy: boolean; sendAfterBuyToUser: boolean; }) {
this.loading = true;
@@ -214,7 +257,19 @@ export default defineComponent({
.then(() => {
this.loading = false;
})
- }
+ },
+ formatPrice(price: number): string {
+ return new Intl.NumberFormat('fa-IR').format(price);
+ },
+ selectCustomAmount() {
+ this.isCustomAmount = true;
+ this.smsCharge = Number(this.customAmount);
+ },
+ handleCustomAmountInput() {
+ if (this.isCustomAmount) {
+ this.smsCharge = Number(this.customAmount);
+ }
+ },
},
beforeMount() {
this.loadData();
@@ -223,5 +278,106 @@ export default defineComponent({
\ No newline at end of file
diff --git a/webUI/src/views/user/manager/settings/system.vue b/webUI/src/views/user/manager/settings/system.vue
index 61397bf..45462ec 100644
--- a/webUI/src/views/user/manager/settings/system.vue
+++ b/webUI/src/views/user/manager/settings/system.vue
@@ -18,6 +18,11 @@ export default defineComponent({
value: 'pec',
props: { subtitle: 'pec.ir' },
},
+ {
+ title: 'پیپینگ',
+ value: 'payping',
+ props: { subtitle: 'payping.ir' },
+ },
],
systemInfo: {
keywords: '',
@@ -26,6 +31,7 @@ export default defineComponent({
appSite: '',
activeGateway:'zarinpal',
parsianGatewayAPI: '',
+ paypingKey: '',
},
loading: true,
}
@@ -86,6 +92,10 @@ export default defineComponent({
+
+
+
{{ $t('dialog.save') }}