fix some bugs from accounting 4
This commit is contained in:
@@ -274,20 +274,20 @@ class ZarinController extends Controller
|
|||||||
* پیدا کردن کار/کالای محصول در زرین.
|
* پیدا کردن کار/کالای محصول در زرین.
|
||||||
* اول infokarbarcodi (اگر روی آن سرور فعال باشد)؛ وگرنه infosakhte (لیست کامل).
|
* اول infokarbarcodi (اگر روی آن سرور فعال باشد)؛ وگرنه infosakhte (لیست کامل).
|
||||||
*/
|
*/
|
||||||
private function findZarinKarForProduct(Product $product, $goroheKar = null)
|
private function findZarinKarForProduct(Product $product, $goroheKar = null, bool $exactOnly = false)
|
||||||
{
|
{
|
||||||
$goroheKar = $goroheKar ?: $this->zarinDefaultGoroheKar();
|
$goroheKar = $goroheKar ?: $this->zarinDefaultGoroheKar();
|
||||||
$productName = $this->normalizeZarinName($product->title);
|
$productName = $this->normalizeZarinName($product->title);
|
||||||
|
|
||||||
$fromBarcode = $this->findZarinKarInInfokarbarcodi($productName, $goroheKar);
|
$fromBarcode = $this->findZarinKarInInfokarbarcodi($productName, $goroheKar, $exactOnly);
|
||||||
if ($fromBarcode) {
|
if ($fromBarcode) {
|
||||||
return $fromBarcode;
|
return $fromBarcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->findZarinKarInInfosakhte($productName, $goroheKar);
|
return $this->findZarinKarInInfosakhte($productName, $goroheKar, $exactOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function matchZarinKarRow(string $productName, array $row): ?array
|
private function matchZarinKarRow(string $productName, array $row, bool $exactOnly = false): ?array
|
||||||
{
|
{
|
||||||
$name = $row['nameKar']
|
$name = $row['nameKar']
|
||||||
?? $row['nam_kar_sakhte']
|
?? $row['nam_kar_sakhte']
|
||||||
@@ -300,26 +300,41 @@ class ZarinController extends Controller
|
|||||||
$rowName = $this->normalizeZarinName($name);
|
$rowName = $this->normalizeZarinName($name);
|
||||||
$idKar = $this->extractUsableZarinKarId($row);
|
$idKar = $this->extractUsableZarinKarId($row);
|
||||||
|
|
||||||
if (!$idKar) {
|
if (!$idKar || $rowName === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rowName === $productName) {
|
||||||
|
return [
|
||||||
|
'idKar' => $idKar,
|
||||||
|
'row' => $row,
|
||||||
|
'match' => 'exact',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($exactOnly) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$rowName === $productName ||
|
|
||||||
$this->containsText($rowName, $productName) ||
|
$this->containsText($rowName, $productName) ||
|
||||||
$this->containsText($productName, $rowName)
|
$this->containsText($productName, $rowName)
|
||||||
) {
|
) {
|
||||||
return [
|
return [
|
||||||
'idKar' => $idKar,
|
'idKar' => $idKar,
|
||||||
'row' => $row,
|
'row' => $row,
|
||||||
|
'match' => 'fuzzy',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function findZarinKarInInfokarbarcodi(string $productName, $goroheKar): ?array
|
private function findZarinKarInInfokarbarcodi(string $productName, $goroheKar, bool $exactOnly = false): ?array
|
||||||
{
|
{
|
||||||
|
$exact = null;
|
||||||
|
$fuzzy = null;
|
||||||
|
|
||||||
for ($page = 1; $page <= 10; $page++) {
|
for ($page = 1; $page <= 10; $page++) {
|
||||||
$response = $this->zarinRequest([
|
$response = $this->zarinRequest([
|
||||||
'kind' => 'infokarbarcodi',
|
'kind' => 'infokarbarcodi',
|
||||||
@@ -343,10 +358,15 @@ class ZarinController extends Controller
|
|||||||
if (!is_array($row)) {
|
if (!is_array($row)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$hit = $this->matchZarinKarRow($productName, $row);
|
$hit = $this->matchZarinKarRow($productName, $row, $exactOnly);
|
||||||
if ($hit) {
|
if (!$hit) {
|
||||||
return $hit;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (($hit['match'] ?? '') === 'exact') {
|
||||||
|
$exact = $hit;
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
$fuzzy ??= $hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($rows) < 250) {
|
if (count($rows) < 250) {
|
||||||
@@ -354,11 +374,11 @@ class ZarinController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return $exact ?? ($exactOnly ? null : $fuzzy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** لیست کارهای ساخته — فیلد nam_kar_sakhte / id (تستشده روی API زرین) */
|
/** لیست کارهای ساخته — فیلد nam_kar_sakhte / id (تستشده روی API زرین) */
|
||||||
private function findZarinKarInInfosakhte(string $productName, $goroheKar): ?array
|
private function findZarinKarInInfosakhte(string $productName, $goroheKar, bool $exactOnly = false): ?array
|
||||||
{
|
{
|
||||||
$response = $this->zarinRequest([
|
$response = $this->zarinRequest([
|
||||||
'kind' => 'infosakhte',
|
'kind' => 'infosakhte',
|
||||||
@@ -375,29 +395,42 @@ class ZarinController extends Controller
|
|||||||
|
|
||||||
$noeKar = (string) $this->zarinDefaultNoeKar();
|
$noeKar = (string) $this->zarinDefaultNoeKar();
|
||||||
$gorohe = (string) $goroheKar;
|
$gorohe = (string) $goroheKar;
|
||||||
$preferred = null;
|
$exactPreferred = null;
|
||||||
$fallback = null;
|
$exactFallback = null;
|
||||||
|
$fuzzyPreferred = null;
|
||||||
|
$fuzzyFallback = null;
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
if (!is_array($row)) {
|
if (!is_array($row)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$hit = $this->matchZarinKarRow($productName, $row);
|
$hit = $this->matchZarinKarRow($productName, $row, $exactOnly);
|
||||||
if (!$hit) {
|
if (!$hit) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$idGp = (string) ($row['idGp'] ?? $row['idgp'] ?? '');
|
$idGp = (string) ($row['idGpFelez'] ?? $row['idgpfelez'] ?? $row['gorooheKar'] ?? '');
|
||||||
if ($idGp !== '' && ($idGp === $gorohe || $idGp === $noeKar)) {
|
$inGroup = $idGp !== '' && ($idGp === $gorohe || $idGp === $noeKar);
|
||||||
$preferred = $hit;
|
$isExact = ($hit['match'] ?? '') === 'exact';
|
||||||
|
|
||||||
|
if ($isExact && $inGroup) {
|
||||||
|
$exactPreferred = $hit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($fallback === null) {
|
if ($isExact) {
|
||||||
$fallback = $hit;
|
$exactFallback ??= $hit;
|
||||||
|
} elseif ($inGroup) {
|
||||||
|
$fuzzyPreferred ??= $hit;
|
||||||
|
} else {
|
||||||
|
$fuzzyFallback ??= $hit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $preferred ?? $fallback;
|
if ($exactOnly) {
|
||||||
|
return $exactPreferred ?? $exactFallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $exactPreferred ?? $exactFallback ?? $fuzzyPreferred ?? $fuzzyFallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getZarinKarById($idKar)
|
private function getZarinKarById($idKar)
|
||||||
@@ -423,14 +456,11 @@ class ZarinController extends Controller
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rowId = $row['pkFelez']
|
// infosakhte: کد کار = id (نه pkFelez)
|
||||||
?? $row['pkfelez']
|
$rowId = $row['idKar']
|
||||||
?? $row['PKFelez']
|
|
||||||
?? $row['id']
|
|
||||||
?? $row['idKar']
|
|
||||||
?? $row['idkar']
|
?? $row['idkar']
|
||||||
?? $row['zarrinId']
|
?? $row['IDKar']
|
||||||
?? $row['zarinId']
|
?? $row['id']
|
||||||
?? null;
|
?? null;
|
||||||
if ((string) $rowId === (string) $idKar) {
|
if ((string) $rowId === (string) $idKar) {
|
||||||
return $row;
|
return $row;
|
||||||
@@ -440,19 +470,24 @@ class ZarinController extends Controller
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* کد کار قابل استفاده برای sabtSanadTedadi.
|
||||||
|
* infosakhte → فیلد id؛ addFelezsakhteModel → idKar.
|
||||||
|
* pkFelez هرگز idKar نیست.
|
||||||
|
*/
|
||||||
private function extractUsableZarinKarId(array $row)
|
private function extractUsableZarinKarId(array $row)
|
||||||
{
|
{
|
||||||
foreach ([
|
foreach ([
|
||||||
'zarrinId',
|
|
||||||
'zarinId',
|
|
||||||
'idKar',
|
'idKar',
|
||||||
'idkar',
|
'idkar',
|
||||||
'IDKar',
|
'IDKar',
|
||||||
'id',
|
'id',
|
||||||
|
'zarrinId',
|
||||||
|
'zarinId',
|
||||||
'code',
|
'code',
|
||||||
'Code',
|
'Code',
|
||||||
] as $key) {
|
] as $key) {
|
||||||
if (isset($row[$key]) && is_numeric($row[$key])) {
|
if (isset($row[$key]) && is_numeric($row[$key]) && (int) $row[$key] > 0) {
|
||||||
return (int) $row[$key];
|
return (int) $row[$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,6 +495,36 @@ class ZarinController extends Controller
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** پاسخ addFelezsakhteModel: {"state":true,"msg":"...","idKar":3130} */
|
||||||
|
private function extractIdKarFromCreateResponse($body): ?int
|
||||||
|
{
|
||||||
|
if (!is_array($body)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (['idKar', 'idkar', 'IDKar'] as $key) {
|
||||||
|
if (isset($body[$key]) && is_numeric($body[$key]) && (int) $body[$key] > 0) {
|
||||||
|
return (int) $body[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $body['data'] ?? null;
|
||||||
|
if (is_array($data)) {
|
||||||
|
if (isset($data[0]) && is_array($data[0])) {
|
||||||
|
$fromRow = $this->extractUsableZarinKarId($data[0]);
|
||||||
|
if ($fromRow) {
|
||||||
|
return $fromRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$fromData = $this->extractUsableZarinKarId($data);
|
||||||
|
if ($fromData) {
|
||||||
|
return $fromData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private function createZarinKarForProduct(Product $product)
|
private function createZarinKarForProduct(Product $product)
|
||||||
{
|
{
|
||||||
$params = [
|
$params = [
|
||||||
@@ -493,11 +558,23 @@ class ZarinController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$body = $response->json();
|
$body = $response->json();
|
||||||
|
$createdIdKar = $this->extractIdKarFromCreateResponse(is_array($body) ? $body : null);
|
||||||
|
|
||||||
$createdPkFelez = $body['data'][0]['pkFelez']
|
// اولویت با idKar برگشتی از ساخت — جستجوی فازی نام میتواند کالای اشتباه بچسباند
|
||||||
?? $body['data']['pkFelez']
|
if ($createdIdKar) {
|
||||||
?? $body['pkFelez']
|
$product->finance_p_name = (string) $createdIdKar;
|
||||||
?? null;
|
$product->save();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ok' => true,
|
||||||
|
'source' => 'created_idKar',
|
||||||
|
'idKar' => $createdIdKar,
|
||||||
|
'product' => $product->fresh(),
|
||||||
|
'zarin_row' => $this->getZarinKarById($createdIdKar),
|
||||||
|
'zarin_response' => $body,
|
||||||
|
'sent_params_success' => $params,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$foundAfterCreate = $this->findZarinKarForProduct($product, $this->zarinDefaultGoroheKar());
|
$foundAfterCreate = $this->findZarinKarForProduct($product, $this->zarinDefaultGoroheKar());
|
||||||
|
|
||||||
@@ -512,16 +589,14 @@ class ZarinController extends Controller
|
|||||||
'product' => $product->fresh(),
|
'product' => $product->fresh(),
|
||||||
'zarin_row' => $foundAfterCreate['row'],
|
'zarin_row' => $foundAfterCreate['row'],
|
||||||
'zarin_response' => $body,
|
'zarin_response' => $body,
|
||||||
'created_pkFelez' => $createdPkFelez,
|
|
||||||
'sent_params_success' => $params,
|
'sent_params_success' => $params,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'ok' => false,
|
'ok' => false,
|
||||||
'message' => 'زرین کالا را ساخت، اما idKar قابل استفاده از infosakhte/infokarbarcodi پیدا نشد.',
|
'message' => 'زرین کالا را ساخت، اما idKar قابل استفاده برنگشت.',
|
||||||
'status_code' => 422,
|
'status_code' => 422,
|
||||||
'created_pkFelez' => $createdPkFelez,
|
|
||||||
'zarin_response' => $body,
|
'zarin_response' => $body,
|
||||||
'sent_params' => $params,
|
'sent_params' => $params,
|
||||||
];
|
];
|
||||||
@@ -530,48 +605,93 @@ class ZarinController extends Controller
|
|||||||
private function ensureZarinKarForProduct(Product $product, $forceCreate = false)
|
private function ensureZarinKarForProduct(Product $product, $forceCreate = false)
|
||||||
{
|
{
|
||||||
$currentIdKar = $product->finance_p_name;
|
$currentIdKar = $product->finance_p_name;
|
||||||
|
$productName = $this->normalizeZarinName($product->title);
|
||||||
|
|
||||||
if (!$forceCreate && !empty($currentIdKar) && is_numeric($currentIdKar)) {
|
if (!$forceCreate && !empty($currentIdKar) && is_numeric($currentIdKar)) {
|
||||||
$existingRow = $this->getZarinKarById($currentIdKar);
|
$existingRow = $this->getZarinKarById($currentIdKar);
|
||||||
|
|
||||||
if ($existingRow) {
|
if ($existingRow) {
|
||||||
$usableIdKar = $this->extractUsableZarinKarId($existingRow) ?: (int) $currentIdKar;
|
$rowName = $this->normalizeZarinName(
|
||||||
|
$existingRow['nameKar']
|
||||||
|
?? $existingRow['nam_kar_sakhte']
|
||||||
|
?? $existingRow['nam']
|
||||||
|
?? $existingRow['name']
|
||||||
|
?? $existingRow['namKar']
|
||||||
|
?? $existingRow['title']
|
||||||
|
?? ''
|
||||||
|
);
|
||||||
|
// اگر idKar موجود مال کالای دیگری است (مثلاً شمش برای گوی) قبول نکن
|
||||||
|
if ($rowName !== '' && $productName !== '' && $rowName !== $productName) {
|
||||||
|
$this->clearProductZarinKar($product);
|
||||||
|
$product->refresh();
|
||||||
|
} else {
|
||||||
|
$usableIdKar = $this->extractUsableZarinKarId($existingRow) ?: (int) $currentIdKar;
|
||||||
|
|
||||||
if ((string) $product->finance_p_name !== (string) $usableIdKar) {
|
if ((string) $product->finance_p_name !== (string) $usableIdKar) {
|
||||||
$product->finance_p_name = (string) $usableIdKar;
|
$product->finance_p_name = (string) $usableIdKar;
|
||||||
$product->save();
|
$product->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ok' => true,
|
||||||
|
'source' => 'existing_verified',
|
||||||
|
'idKar' => (int) $usableIdKar,
|
||||||
|
'product' => $product->fresh(),
|
||||||
|
'zarin_row' => $existingRow,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
return [
|
// finance_p_name کهنه / اشتباه — پاک کن تا دوباره پیدا یا ساخته شود
|
||||||
'ok' => true,
|
$this->clearProductZarinKar($product);
|
||||||
'source' => 'existing_verified',
|
$product->refresh();
|
||||||
'idKar' => (int) $usableIdKar,
|
|
||||||
'product' => $product->fresh(),
|
|
||||||
'zarin_row' => $existingRow,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$forceCreate) {
|
// بعد از خطای «کد کار اشتباه»: فقط تطبیق دقیق نام، نه فازی
|
||||||
$found = $this->findZarinKarForProduct($product, $this->zarinDefaultGoroheKar());
|
$exactOnly = (bool) $forceCreate;
|
||||||
|
$found = $this->findZarinKarForProduct($product, $this->zarinDefaultGoroheKar(), $exactOnly);
|
||||||
|
|
||||||
if ($found && !empty($found['idKar']) && is_numeric($found['idKar'])) {
|
if ($found && !empty($found['idKar']) && is_numeric($found['idKar'])) {
|
||||||
$product->finance_p_name = (string) $found['idKar'];
|
$product->finance_p_name = (string) $found['idKar'];
|
||||||
$product->save();
|
$product->save();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'ok' => true,
|
'ok' => true,
|
||||||
'source' => 'found_by_name',
|
'source' => $exactOnly ? 'found_exact_after_invalid' : 'found_by_name',
|
||||||
'idKar' => (int) $found['idKar'],
|
'idKar' => (int) $found['idKar'],
|
||||||
'product' => $product->fresh(),
|
'product' => $product->fresh(),
|
||||||
'zarin_row' => $found['row'],
|
'zarin_row' => $found['row'],
|
||||||
];
|
'match' => $found['match'] ?? null,
|
||||||
}
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->createZarinKarForProduct($product);
|
return $this->createZarinKarForProduct($product);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function clearProductZarinKar(Product $product): void
|
||||||
|
{
|
||||||
|
if ($product->finance_p_name === null || $product->finance_p_name === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$product->finance_p_name = null;
|
||||||
|
$product->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isInvalidZarinKarError($response, ?string $httpError = null): bool
|
||||||
|
{
|
||||||
|
$haystack = '';
|
||||||
|
if (is_string($httpError)) {
|
||||||
|
$haystack .= $httpError;
|
||||||
|
}
|
||||||
|
if (is_array($response)) {
|
||||||
|
$haystack .= ' ' . json_encode($response, JSON_UNESCAPED_UNICODE);
|
||||||
|
} elseif (is_string($response)) {
|
||||||
|
$haystack .= ' ' . $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_contains($haystack, 'کد کار اشتباه');
|
||||||
|
}
|
||||||
|
|
||||||
public function table(Request $request)
|
public function table(Request $request)
|
||||||
{
|
{
|
||||||
$query = Zarin::with('customer')->orderByDesc('id');
|
$query = Zarin::with('customer')->orderByDesc('id');
|
||||||
@@ -1141,10 +1261,17 @@ class ZarinController extends Controller
|
|||||||
'amount' => $syncAmount,
|
'amount' => $syncAmount,
|
||||||
'order_id' => $orderId,
|
'order_id' => $orderId,
|
||||||
'date' => $data['pay_at'] ?? Carbon::now(),
|
'date' => $data['pay_at'] ?? Carbon::now(),
|
||||||
'type' => $mapper->metalLabel($product),
|
'type' => $mapper->zarinSyncTypeLabel($product),
|
||||||
'created_at' => Carbon::now(),
|
'created_at' => Carbon::now(),
|
||||||
'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
|
'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
|
||||||
]);
|
]);
|
||||||
|
if ($existing) {
|
||||||
|
$existing->update([
|
||||||
|
'type' => $mapper->zarinSyncTypeLabel($product),
|
||||||
|
'desc' => $sharh,
|
||||||
|
'amount' => $syncAmount,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($mapper->isCountDoc($product)) {
|
if ($mapper->isCountDoc($product)) {
|
||||||
@@ -1465,11 +1592,18 @@ class ZarinController extends Controller
|
|||||||
'desc' => $sharh,
|
'desc' => $sharh,
|
||||||
'amount' => $syncAmount,
|
'amount' => $syncAmount,
|
||||||
'date' => Carbon::now(),
|
'date' => Carbon::now(),
|
||||||
'type' => $mapper->metalLabel($product),
|
'type' => $mapper->zarinSyncTypeLabel($product),
|
||||||
'created_at' => Carbon::now(),
|
'created_at' => Carbon::now(),
|
||||||
'withdraw_id' => $data['withdraw_id'] ?? null,
|
'withdraw_id' => $data['withdraw_id'] ?? null,
|
||||||
'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
|
'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
|
||||||
]);
|
]);
|
||||||
|
if ($existing) {
|
||||||
|
$existing->update([
|
||||||
|
'type' => $mapper->zarinSyncTypeLabel($product),
|
||||||
|
'desc' => $sharh,
|
||||||
|
'amount' => $syncAmount,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
if ($existing && empty($existing->data)) {
|
if ($existing && empty($existing->data)) {
|
||||||
$existing->update(['data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)]);
|
$existing->update(['data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)]);
|
||||||
@@ -1525,6 +1659,7 @@ class ZarinController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* سند تعدادی زرین (سکه / شمش / گوی / مکعب).
|
* سند تعدادی زرین (سکه / شمش / گوی / مکعب).
|
||||||
|
* در زرین همه با sabtSanadTedadi میروند؛ تفکیک فقط با idKar جداگانهٔ هر محصول است.
|
||||||
*/
|
*/
|
||||||
private function postZarinCountDoc(
|
private function postZarinCountDoc(
|
||||||
Zarin $zarin,
|
Zarin $zarin,
|
||||||
@@ -1542,46 +1677,71 @@ class ZarinController extends Controller
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$kar = $this->ensureZarinKarForProduct($product);
|
|
||||||
if (empty($kar['ok']) || empty($kar['idKar'])) {
|
|
||||||
$this->sync()->markFailed($zarin, $kar ?? null, $kar['message'] ?? 'کد کار زرین برای محصول یافت نشد');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($fi <= 0) {
|
if ($fi <= 0) {
|
||||||
$fi = 1;
|
$fi = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$http = $this->zarinRequest([
|
$retriedInvalidKar = false;
|
||||||
'kind' => 'sabtSanadTedadi',
|
|
||||||
'idHesab' => $customer->moshtari_code,
|
|
||||||
'idKar' => (int) $kar['idKar'],
|
|
||||||
'fi' => $fi,
|
|
||||||
'tedad' => $tedad,
|
|
||||||
'parDar' => $parDar,
|
|
||||||
'sharh' => $sharh,
|
|
||||||
'uid' => $uid,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$http) {
|
while (true) {
|
||||||
$this->sync()->markFailed($zarin, null, 'تنظیمات زرین کامل نیست');
|
$kar = $this->ensureZarinKarForProduct($product, $retriedInvalidKar);
|
||||||
return 'تنظیمات زرین کامل نیست. zarin_api یا zarin_token تنظیم نشده است.';
|
if (empty($kar['ok']) || empty($kar['idKar'])) {
|
||||||
}
|
$this->sync()->markFailed($zarin, $kar ?? null, $kar['message'] ?? 'کد کار زرین برای محصول یافت نشد');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
[$response, $httpError] = $this->zarinDecodeResponse($http);
|
$http = $this->zarinRequest([
|
||||||
if ($httpError) {
|
'kind' => 'sabtSanadTedadi',
|
||||||
$this->sync()->markFailed($zarin, $response ?? $httpError, $httpError);
|
'idHesab' => $customer->moshtari_code,
|
||||||
|
'idKar' => (int) $kar['idKar'],
|
||||||
|
'fi' => $fi,
|
||||||
|
'tedad' => $tedad,
|
||||||
|
'parDar' => $parDar,
|
||||||
|
'sharh' => $sharh,
|
||||||
|
'uid' => $uid,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$http) {
|
||||||
|
$this->sync()->markFailed($zarin, null, 'تنظیمات زرین کامل نیست');
|
||||||
|
return 'تنظیمات زرین کامل نیست. zarin_api یا zarin_token تنظیم نشده است.';
|
||||||
|
}
|
||||||
|
|
||||||
|
[$response, $httpError] = $this->zarinDecodeResponse($http);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!$retriedInvalidKar
|
||||||
|
&& $this->isInvalidZarinKarError($response, $httpError)
|
||||||
|
) {
|
||||||
|
$this->clearProductZarinKar($product);
|
||||||
|
$product->refresh();
|
||||||
|
$retriedInvalidKar = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($httpError) {
|
||||||
|
$this->sync()->markFailed($zarin, $response ?? $httpError, $httpError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$flat = $this->extractResponseRow(is_array($response) ? $response : null);
|
||||||
|
if ($this->sync()->responseOk(is_array($response) ? $response : []) || $this->sync()->responseOk($flat)) {
|
||||||
|
$this->sync()->markSuccess($zarin, is_array($response) ? $response : $flat, $data);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!$retriedInvalidKar
|
||||||
|
&& $this->isInvalidZarinKarError($response)
|
||||||
|
) {
|
||||||
|
$this->clearProductZarinKar($product);
|
||||||
|
$product->refresh();
|
||||||
|
$retriedInvalidKar = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sync()->markFailed($zarin, $response, 'ثبت سند تعدادی در زرین ناموفق بود');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$flat = $this->extractResponseRow(is_array($response) ? $response : null);
|
|
||||||
if ($this->sync()->responseOk(is_array($response) ? $response : []) || $this->sync()->responseOk($flat)) {
|
|
||||||
$this->sync()->markSuccess($zarin, is_array($response) ? $response : $flat, $data);
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sync()->markFailed($zarin, $response, 'ثبت سند تعدادی در زرین ناموفق بود');
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -194,6 +194,20 @@ class AccountingProductDocMapper
|
|||||||
return 'طلا';
|
return 'طلا';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* برچسب ستون type جدول sync زرین: تعدادی → سکه/شمش/کارساخته؛ وزنی → طلا/نقره.
|
||||||
|
*
|
||||||
|
* @param Product|array|null $product
|
||||||
|
*/
|
||||||
|
public function zarinSyncTypeLabel($product): string
|
||||||
|
{
|
||||||
|
if ($this->isCountDoc($product)) {
|
||||||
|
return $this->kindLabel($this->resolveKind($product));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->metalLabel($product);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve Product model from storeTrade/walletGold payload.
|
* Resolve Product model from storeTrade/walletGold payload.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user