update for Moadian plugin

This commit is contained in:
Gloomy 2025-08-18 20:33:09 +00:00
parent dd78e12a7a
commit 484c7a0a64

View file

@ -3,7 +3,7 @@
/** /**
* Developed by Mohammad Rezai * Developed by Mohammad Rezai
* https://pirouz.xyz 2025-07-28 * https://pirouz.xyz 2025-07-28
*/ */
namespace App\Controller\Plugins; namespace App\Controller\Plugins;
@ -25,7 +25,7 @@ use DateTime;
class TaxSettingsController extends AbstractController class TaxSettingsController extends AbstractController
{ {
private function getMoadianBaseUrl(registryMGR $registryMGR): string private function getMoadianBaseUrl(registryMGR $registryMGR): string
{ {
$sandboxMode = filter_var($registryMGR->get('system_settings', 'tax_system_sandbox_mode'), FILTER_VALIDATE_BOOLEAN); $sandboxMode = filter_var($registryMGR->get('system_settings', 'tax_system_sandbox_mode'), FILTER_VALIDATE_BOOLEAN);
@ -154,14 +154,14 @@ class TaxSettingsController extends AbstractController
$params = $request->getPayload()->all(); $params = $request->getPayload()->all();
$personType = $params['personType'] ?? 'natural'; $personType = $params['personType'] ?? 'natural';
if (empty($params['nationalId'])) { if (empty($params['nationalId'])) {
return $this->json([ return $this->json([
'success' => false, 'success' => false,
'message' => 'شناسه ملی الزامی است' 'message' => 'شناسه ملی الزامی است'
]); ]);
} }
if ($personType === 'legal') { if ($personType === 'legal') {
if (empty($params['nameFa']) || empty($params['nameEn']) || empty($params['email'])) { if (empty($params['nameFa']) || empty($params['nameEn']) || empty($params['email'])) {
return $this->json([ return $this->json([
@ -174,15 +174,15 @@ class TaxSettingsController extends AbstractController
try { try {
$privateKey = $this->generatePrivateKey(); $privateKey = $this->generatePrivateKey();
$publicKey = $this->generatePublicKey($privateKey); $publicKey = $this->generatePublicKey($privateKey);
$businessId = is_object($acc['bid']) ? $acc['bid']->getId() : $acc['bid']; $businessId = is_object($acc['bid']) ? $acc['bid']->getId() : $acc['bid'];
$response = [ $response = [
'success' => true, 'success' => true,
'privateKey' => $privateKey, 'privateKey' => $privateKey,
'publicKey' => $publicKey 'publicKey' => $publicKey
]; ];
if ($personType === 'legal') { if ($personType === 'legal') {
$csr = $this->generateCSR($privateKey, $params); $csr = $this->generateCSR($privateKey, $params);
$response['csr'] = $csr; $response['csr'] = $csr;
@ -555,6 +555,7 @@ class TaxSettingsController extends AbstractController
$itemDiscountType = $row->getDiscountType() ?? 'fixed'; $itemDiscountType = $row->getDiscountType() ?? 'fixed';
$itemDiscountPercent = $row->getDiscountPercent() ?? 0; $itemDiscountPercent = $row->getDiscountPercent() ?? 0;
$itemTax = $row->getTax() ?? 0; $itemTax = $row->getTax() ?? 0;
$count = $row->getCommdityCount() ?? 0;
if ($itemDiscountType === 'percent' && $itemDiscountPercent > 0) { if ($itemDiscountType === 'percent' && $itemDiscountPercent > 0) {
$originalPrice = $basePrice / (1 - ($itemDiscountPercent / 100)); $originalPrice = $basePrice / (1 - ($itemDiscountPercent / 100));
@ -562,8 +563,8 @@ class TaxSettingsController extends AbstractController
} else { } else {
$originalPrice = $basePrice + $itemDiscount; $originalPrice = $basePrice + $itemDiscount;
} }
$unitPrice = $count > 0 ? $originalPrice / $count : 0;
$unitPrice = $row->getCommdityCount() > 0 ? $originalPrice / $row->getCommdityCount() : 0; $es = $count > 0 ? ($unitPrice * $count) : $originalPrice;
$netPrice = $basePrice; $netPrice = $basePrice;
$totalInvoice += $netPrice; $totalInvoice += $netPrice;
@ -574,8 +575,9 @@ class TaxSettingsController extends AbstractController
'name' => $row->getCommodity()->getName(), 'name' => $row->getCommodity()->getName(),
'code' => $row->getCommodity()->getCode() 'code' => $row->getCommodity()->getCode()
], ],
'count' => $row->getCommdityCount(), 'count' => $count,
'price' => $unitPrice, 'price' => $unitPrice,
'prdis' => $es,
'discountPercent' => $itemDiscountPercent, 'discountPercent' => $itemDiscountPercent,
'discountAmount' => $itemDiscount, 'discountAmount' => $itemDiscount,
'total' => $netPrice, 'total' => $netPrice,
@ -663,7 +665,7 @@ class TaxSettingsController extends AbstractController
$rowNumber = 1; $rowNumber = 1;
foreach ($data['items'] as $item) { foreach ($data['items'] as $item) {
$commodity = $item['name']; $commodity = $item['name'];
if (empty($commodity['code'])) { if (empty($commodity['code'])) {
$errors[] = "ردیف {$rowNumber}: کد کالا/خدمت تعریف نشده است"; $errors[] = "ردیف {$rowNumber}: کد کالا/خدمت تعریف نشده است";
} }
@ -832,22 +834,22 @@ class TaxSettingsController extends AbstractController
$moadian->setToken($token); $moadian->setToken($token);
$invoice = $taxInvoice->getInvoice(); $invoice = $taxInvoice->getInvoice();
try { try {
if (!$invoice) { if (!$invoice) {
throw new \Exception('فاکتور معتبر نیست'); throw new \Exception('فاکتور معتبر نیست');
} }
$validationResult = $this->validateInvoiceForTax($invoice); $validationResult = $this->validateInvoiceForTax($invoice);
if (!$validationResult['valid']) { if (!$validationResult['valid']) {
throw new \Exception($validationResult['message']); throw new \Exception($validationResult['message']);
} }
$invoiceDto = $this->buildInvoiceDto($invoice, $moadian, $taxSettings->getEconomicCode()); $invoiceDto = $this->buildInvoiceDto($invoice, $moadian, $taxSettings->getEconomicCode());
if (!$invoiceDto) { if (!$invoiceDto) {
throw new \Exception('خطا در آماده‌سازی فاکتور: خطا در ساخت DTO فاکتور'); throw new \Exception('خطا در آماده‌سازی فاکتور: خطا در ساخت DTO فاکتور');
} }
$response = $moadian->sendInvoices([$invoiceDto]); $response = $moadian->sendInvoices([$invoiceDto]);
} catch (\Exception $e) { } catch (\Exception $e) {
return $this->json([ return $this->json([
@ -1111,7 +1113,7 @@ class TaxSettingsController extends AbstractController
$vra = round(($itemTax / $itemTotal) * 100, 2); $vra = round(($itemTax / $itemTotal) * 100, 2);
$invoiceType = $invoice->getType() ?? 'sell'; $invoiceType = $invoice->getType() ?? 'sell';
switch ($invoiceType) { switch ($invoiceType) {
case 'return_sell': case 'return_sell':
case 'return_buy': case 'return_buy':
@ -1165,7 +1167,7 @@ class TaxSettingsController extends AbstractController
$buyerNationalId = null; $buyerNationalId = null;
$buyerEconomicCode = null; $buyerEconomicCode = null;
$buyerPostalCode = null; $buyerPostalCode = null;
$buyerPerson = null; $buyerPerson = null;
foreach ($invoice->getHesabdariRows() as $row) { foreach ($invoice->getHesabdariRows() as $row) {
if ($row->getPerson()) { if ($row->getPerson()) {
@ -1182,7 +1184,7 @@ class TaxSettingsController extends AbstractController
if (empty($buyerNationalId) || trim($buyerNationalId) === '') { if (empty($buyerNationalId) || trim($buyerNationalId) === '') {
$buyerNationalId = null; $buyerNationalId = null;
} }
if (empty($buyerEconomicCode) || trim($buyerEconomicCode) === '') { if (empty($buyerEconomicCode) || trim($buyerEconomicCode) === '') {
$buyerEconomicCode = null; $buyerEconomicCode = null;
} }
@ -1193,7 +1195,7 @@ class TaxSettingsController extends AbstractController
} }
$personType = 1; $personType = 1;
if (strlen($buyerNationalId) == 11) { if (strlen($buyerNationalId) == 11) {
$personType = 2; $personType = 2;
} }
@ -1229,7 +1231,7 @@ class TaxSettingsController extends AbstractController
->setScc(null) ->setScc(null)
->setCrn(null) ->setCrn(null)
->setBillid(null) ->setBillid(null)
->setTprdis($data['totalInvoice']) ->setTprdis(array_sum(array_column($data['items'], 'prdis')))
->setTdis($data['totalDiscount']) ->setTdis($data['totalDiscount'])
->setTadis($data['totalInvoice'] - $data['totalDiscount']) ->setTadis($data['totalInvoice'] - $data['totalDiscount'])
->setTvam($totalTax) ->setTvam($totalTax)
@ -1241,13 +1243,23 @@ class TaxSettingsController extends AbstractController
->setTvop(null) ->setTvop(null)
->setTax17(0); ->setTax17(0);
$bodyItems = []; $bodyItems = [];
foreach ($data['items'] as $item) { foreach ($data['items'] as $item) {
$itemTax = $item['tax']; $itemTax = $item['tax'];
$itemTotal = $item['total'] + $itemTax;
$vra = $this->calculateVra($item['total'], $itemTax, $invoice); $vra = $this->calculateVra($item['total'], $itemTax, $invoice);
$prdis = $item['count'] * $item['price'];
$adis = $prdis - $item['discountAmount'];
$ks = ($adis * $vra) / 100;
$ks2 = 0;
$ks3 = 0;
$os = $adis + $ks + $ks2 + $ks3;
$bodyDto = (new \SnappMarketPro\Moadian\Dto\InvoiceBodyDto()) $bodyDto = (new \SnappMarketPro\Moadian\Dto\InvoiceBodyDto())
->setSstid($this->getCommodityTaxCodeFromInvoice($invoice, $item['name']['id'])) ->setSstid($this->getCommodityTaxCodeFromInvoice($invoice, $item['name']['id']))
->setSstt($item['name']['name']) ->setSstt($item['name']['name'])
@ -1257,11 +1269,11 @@ class TaxSettingsController extends AbstractController
->setCfee(null) ->setCfee(null)
->setCut(null) ->setCut(null)
->setExr(null) ->setExr(null)
->setPrdis($item['total']) ->setPrdis($prdis)
->setDis($item['discountAmount']) ->setDis($item['discountAmount'])
->setAdis($item['total'] - $item['discountAmount']) ->setAdis($adis)
->setVra($vra) ->setVra($vra)
->setVam($itemTax) ->setVam($ks)
->setOdt(null) ->setOdt(null)
->setOdr(null) ->setOdr(null)
->setOdam(null) ->setOdam(null)
@ -1275,7 +1287,7 @@ class TaxSettingsController extends AbstractController
->setCop(null) ->setCop(null)
->setVop(null) ->setVop(null)
->setBsrn(null) ->setBsrn(null)
->setTsstam($itemTotal); ->setTsstam($os);
$bodyItems[] = $bodyDto; $bodyItems[] = $bodyDto;
} }
@ -1419,7 +1431,7 @@ class TaxSettingsController extends AbstractController
} }
$invoice = $taxInvoice->getInvoice(); $invoice = $taxInvoice->getInvoice();
if (!$invoice) { if (!$invoice) {
$results[] = [ $results[] = [
'id' => $id, 'id' => $id,
@ -1430,7 +1442,7 @@ class TaxSettingsController extends AbstractController
$errorCount++; $errorCount++;
continue; continue;
} }
$validationResult = $this->validateInvoiceForTax($invoice); $validationResult = $this->validateInvoiceForTax($invoice);
if (!$validationResult['valid']) { if (!$validationResult['valid']) {
$results[] = [ $results[] = [
@ -1442,9 +1454,9 @@ class TaxSettingsController extends AbstractController
$errorCount++; $errorCount++;
continue; continue;
} }
$invoiceDto = $this->buildInvoiceDto($invoice, $moadian, $taxSettings->getEconomicCode()); $invoiceDto = $this->buildInvoiceDto($invoice, $moadian, $taxSettings->getEconomicCode());
if (!$invoiceDto) { if (!$invoiceDto) {
$results[] = [ $results[] = [
'id' => $id, 'id' => $id,
'code' => $taxInvoice->getInvoiceCode(), 'code' => $taxInvoice->getInvoiceCode(),
@ -1454,7 +1466,7 @@ class TaxSettingsController extends AbstractController
$errorCount++; $errorCount++;
continue; continue;
} }
$response = $moadian->sendInvoices([$invoiceDto]); $response = $moadian->sendInvoices([$invoiceDto]);
if (isset($response['result'][0]['referenceNumber']) && !empty($response['result'])) { if (isset($response['result'][0]['referenceNumber']) && !empty($response['result'])) {
@ -1583,7 +1595,7 @@ class TaxSettingsController extends AbstractController
} }
$buyerInfo = $this->validateBuyerEconomicInfo($invoice); $buyerInfo = $this->validateBuyerEconomicInfo($invoice);
if (!$buyerInfo['is_valid']) { if (!$buyerInfo['is_valid']) {
return $this->json([ return $this->json([
'success' => false, 'success' => false,
@ -1611,7 +1623,6 @@ class TaxSettingsController extends AbstractController
$buyerEconomicCode = null; $buyerEconomicCode = null;
$missingFields = []; $missingFields = [];
// دریافت شخص خریدار از ردیف‌های فاکتور
foreach ($invoice->getHesabdariRows() as $row) { foreach ($invoice->getHesabdariRows() as $row) {
if ($row->getPerson()) { if ($row->getPerson()) {
$buyerPerson = $row->getPerson(); $buyerPerson = $row->getPerson();
@ -1661,7 +1672,7 @@ class TaxSettingsController extends AbstractController
if (in_array('economic_code', $missingFields)) { if (in_array('economic_code', $missingFields)) {
$missingFieldsText[] = 'کد اقتصادی'; $missingFieldsText[] = 'کد اقتصادی';
} }
$result['message'] = 'اطلاعات اقتصادی خریدار ناقص است. فیلدهای زیر تکمیل نشده‌اند: ' . implode('، ', $missingFieldsText); $result['message'] = 'اطلاعات اقتصادی خریدار ناقص است. فیلدهای زیر تکمیل نشده‌اند: ' . implode('، ', $missingFieldsText);
} else { } else {
$result['message'] = 'اطلاعات اقتصادی خریدار کامل است.'; $result['message'] = 'اطلاعات اقتصادی خریدار کامل است.';