added merge wallet
This commit is contained in:
@@ -74,10 +74,13 @@ class CustomerController extends SuperController
|
||||
public function funds(Request $request,$customer_id)
|
||||
{
|
||||
|
||||
$query_table = Wallet::with(['fund'])->where('owner', $customer_id); // Adjust columns as per your schema
|
||||
// فقط کیف محصولها (نه کیف اصلی) — هر ردیف = موجودی واقعی یک محصول/فلز
|
||||
$query_table = Wallet::with(['product:id,title,metal_id,unit'])
|
||||
->where('owner', $customer_id)
|
||||
->whereNotNull('product_id');
|
||||
TableEngine::create($query_table, $request)
|
||||
->initSearch($this->search)
|
||||
->select(['id', 'owner', 'cash', 'gold','fund_id','created_at', 'updated_at'])
|
||||
->select(['id', 'owner', 'cash', 'gold', 'fund_id', 'product_id', 'created_at', 'updated_at'])
|
||||
->export($query_table);
|
||||
return response()->json($query_table);
|
||||
}
|
||||
|
||||
@@ -42,11 +42,15 @@ class AssetSummaryService
|
||||
|
||||
$catalogById = $catalog->keyBy('id');
|
||||
|
||||
// محصولات متصل به کیف اصلی (main_wallet_products) — موجودیشان = gold کیف اصلی
|
||||
$mainWalletProductIds = $this->configService->mainWalletProductIds();
|
||||
|
||||
$metalsWithProductWallet = $this->metalIdsWithProductWallet($userWallets, $catalogById, $mainWalletProductIds);
|
||||
$inventoryCards = array_merge(
|
||||
$this->buildMeltedInventoryCards($catalog, $catalogById, $mainWallet, $metalIds),
|
||||
$this->buildInventoryCards($userWallets, $catalogById)
|
||||
$this->buildMeltedInventoryCards($catalog, $catalogById, $mainWallet, $metalIds, $metalsWithProductWallet, $mainWalletProductIds),
|
||||
$this->buildInventoryCards($userWallets, $catalogById, $mainWalletProductIds)
|
||||
);
|
||||
$metalTotals = $this->buildMetalTotals($userWallets, $mainWallet, $metalIds, $weightUnit, $catalogById);
|
||||
$metalTotals = $this->buildMetalTotals($userWallets, $mainWallet, $metalIds, $weightUnit, $catalogById, $metalsWithProductWallet, $mainWalletProductIds);
|
||||
$cashWallet = (float) ($mainWallet->cash ?? 0);
|
||||
$assetsRialValue = $this->sumAssetsRialValue($userWallets, $catalogById);
|
||||
$totalRialValue = $cashWallet + $assetsRialValue;
|
||||
@@ -97,15 +101,51 @@ class AssetSummaryService
|
||||
Collection $catalog,
|
||||
Collection $catalogById,
|
||||
?Wallet $mainWallet,
|
||||
array $metalIds
|
||||
array $metalIds,
|
||||
array $metalsWithProductWallet = [],
|
||||
array $mainWalletProductIds = []
|
||||
): array {
|
||||
$cards = [];
|
||||
$mainWalletGrams = Controller::weightToGrams((float) ($mainWallet->gold ?? 0));
|
||||
$assignedMetalIds = [];
|
||||
$mainProductId = $this->configService->mainProductId();
|
||||
|
||||
// حالت صریح: محصولات متصل به کیف اصلی — یک کارت واحد (نماینده = اولین محصول لیست)
|
||||
if ($mainWalletProductIds !== []) {
|
||||
$representative = $this->resolveMainWalletRepresentative($catalogById, $mainWalletProductIds);
|
||||
if (!$representative) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$mainWalletWeight = (float) ($mainWallet->gold ?? 0);
|
||||
if ($mainWalletWeight <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$productPayload = $this->productPayload($representative);
|
||||
|
||||
return [[
|
||||
'product_id' => (int) $representative->id,
|
||||
'title' => (string) $representative->title,
|
||||
'group_type' => $this->meltedGroupTypeLabel($representative),
|
||||
'metal_id' => (int) ($representative->metal_id ?? 0),
|
||||
'quantity' => round($mainWalletWeight, 3),
|
||||
'unit' => Controller::productQuantityUnit($productPayload),
|
||||
'display_type' => 'weight',
|
||||
'unit_weight' => $this->productUnitWeightLabel($representative),
|
||||
'show_in_assets' => $this->shouldShowInAssets($representative),
|
||||
'is_melted' => true,
|
||||
'is_main_wallet' => true,
|
||||
'file' => $this->filePayload($representative),
|
||||
]];
|
||||
}
|
||||
|
||||
foreach ($metalIds as $metalId) {
|
||||
if ($metalId <= 0 || in_array($metalId, $assignedMetalIds, true)) {
|
||||
if (
|
||||
$metalId <= 0
|
||||
|| in_array($metalId, $assignedMetalIds, true)
|
||||
|| in_array((int) $metalId, $metalsWithProductWallet, true)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -186,6 +226,48 @@ class AssetSummaryService
|
||||
return $group !== '' ? $group : 'آبشده';
|
||||
}
|
||||
|
||||
/** اولین محصولِ لیست main_wallet_products که در کاتالوگ فعال است. */
|
||||
private function resolveMainWalletRepresentative(Collection $catalogById, array $mainWalletProductIds): ?Product
|
||||
{
|
||||
foreach ($mainWalletProductIds as $productId) {
|
||||
$product = $catalogById->get((int) $productId);
|
||||
if ($product) {
|
||||
return $product;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** فلزهایی که کاربر روی کیف محصول موجودی دارد — برای جلوگیری از کارت آبشدهٔ تکراری. */
|
||||
private function metalIdsWithProductWallet(Collection $userWallets, Collection $catalogById, array $mainWalletProductIds = []): array
|
||||
{
|
||||
$metalIds = [];
|
||||
|
||||
foreach ($userWallets as $walletLine) {
|
||||
if ($walletLine->product_id === null || (float) $walletLine->gold <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// کیف محصولاتِ متصل به کیف اصلی نادیده گرفته میشود
|
||||
if (in_array((int) $walletLine->product_id, $mainWalletProductIds, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$product = $walletLine->product;
|
||||
if (!$product) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$metalId = (int) ($this->catalogProduct($product, $catalogById)->metal_id ?? 0);
|
||||
if ($metalId > 0) {
|
||||
$metalIds[] = $metalId;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($metalIds));
|
||||
}
|
||||
|
||||
/** محصول نمایشی برای موجودی کیف اصلی هر فلز. */
|
||||
private function resolveDisplayProductForMetal(
|
||||
Collection $catalog,
|
||||
@@ -208,7 +290,7 @@ class AssetSummaryService
|
||||
return $catalog->first(fn (Product $product) => (int) ($product->metal_id ?? 0) === $metalId);
|
||||
}
|
||||
|
||||
private function buildInventoryCards(Collection $userWallets, Collection $catalogById): array
|
||||
private function buildInventoryCards(Collection $userWallets, Collection $catalogById, array $mainWalletProductIds = []): array
|
||||
{
|
||||
$cards = [];
|
||||
|
||||
@@ -217,6 +299,11 @@ class AssetSummaryService
|
||||
continue;
|
||||
}
|
||||
|
||||
// محصول متصل به کیف اصلی دارایی جدا ندارد — کارتش از کیف اصلی ساخته میشود
|
||||
if (in_array((int) $walletLine->product_id, $mainWalletProductIds, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$product = $walletLine->product;
|
||||
if (!$product) {
|
||||
continue;
|
||||
@@ -248,7 +335,9 @@ class AssetSummaryService
|
||||
?Wallet $mainWallet,
|
||||
array $metalIds,
|
||||
string $weightUnit,
|
||||
Collection $catalogById
|
||||
Collection $catalogById,
|
||||
array $metalsWithProductWallet = [],
|
||||
array $mainWalletProductIds = []
|
||||
): array {
|
||||
if ($metalIds === []) {
|
||||
return [];
|
||||
@@ -257,6 +346,13 @@ class AssetSummaryService
|
||||
$mainWalletGrams = Controller::weightToGrams((float) ($mainWallet->gold ?? 0));
|
||||
$totals = [];
|
||||
|
||||
// فلز نمایندهٔ کیف اصلی در حالت main_wallet_products
|
||||
$mainWalletMetalId = null;
|
||||
if ($mainWalletProductIds !== []) {
|
||||
$representative = $this->resolveMainWalletRepresentative($catalogById, $mainWalletProductIds);
|
||||
$mainWalletMetalId = $representative ? (int) ($representative->metal_id ?? 0) : null;
|
||||
}
|
||||
|
||||
foreach ($metalIds as $metalId) {
|
||||
$productGrams = 0.0;
|
||||
|
||||
@@ -265,6 +361,11 @@ class AssetSummaryService
|
||||
continue;
|
||||
}
|
||||
|
||||
// کیف محصولاتِ متصل به کیف اصلی جداگانه شمرده نمیشود
|
||||
if (in_array((int) $walletLine->product_id, $mainWalletProductIds, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$catalogProduct = $this->catalogProduct($walletLine->product, $catalogById);
|
||||
if ((int) ($catalogProduct->metal_id ?? 0) !== (int) $metalId) {
|
||||
continue;
|
||||
@@ -280,7 +381,17 @@ class AssetSummaryService
|
||||
);
|
||||
}
|
||||
|
||||
$meltedGrams = $this->meltedGramsForMetalTotal($mainWalletGrams, $metalId, $metalIds);
|
||||
if ($mainWalletProductIds !== []) {
|
||||
// حالت صریح: کیف اصلی فقط یکبار، زیر فلزِ محصول نماینده
|
||||
$meltedGrams = ($mainWalletMetalId !== null && (int) $metalId === $mainWalletMetalId)
|
||||
? $mainWalletGrams
|
||||
: 0.0;
|
||||
} else {
|
||||
// کیف اصلی فقط برای فلزی که هیچ کیف محصولی ندارد به مجموع اضافه میشود.
|
||||
$meltedGrams = in_array((int) $metalId, $metalsWithProductWallet, true)
|
||||
? 0.0
|
||||
: $this->meltedGramsForMetalTotal($mainWalletGrams, $metalId, $metalIds);
|
||||
}
|
||||
$productWeight = round(Controller::gramsToTradeUnit($productGrams), 3);
|
||||
$meltedWeight = round(Controller::gramsToTradeUnit($meltedGrams), 3);
|
||||
$totalWeight = round($productWeight + $meltedWeight, 3);
|
||||
|
||||
@@ -116,6 +116,38 @@ class ConfigService
|
||||
return in_array($default, self::PRICE_PROVIDERS, true) ? $default : 'montzar';
|
||||
}
|
||||
|
||||
/**
|
||||
* محصولات متصل به کیف اصلی — setting `main_wallet_products`.
|
||||
* مقدار: idها با کاما (مثل «13,25») یا آرایه JSON (مثل «[13,25]»).
|
||||
* موجودی این محصولات = gold کیف اصلی (دارایی جدا ندارند).
|
||||
* فقط opt-in: اگر ست نباشد آرایه خالی برمیگردد و رفتار قبلی حفظ میشود.
|
||||
*/
|
||||
public function mainWalletProductIds(): array
|
||||
{
|
||||
$raw = trim($this->getString('main_wallet_products', ''));
|
||||
if ($raw === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$decoded = json_decode($raw, true);
|
||||
$parts = is_array($decoded) ? $decoded : explode(',', $raw);
|
||||
|
||||
$ids = [];
|
||||
foreach ($parts as $part) {
|
||||
$id = (int) trim((string) $part);
|
||||
if ($id > 0) {
|
||||
$ids[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
public function isMainWalletProduct(int $productId): bool
|
||||
{
|
||||
return in_array($productId, $this->mainWalletProductIds(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* شناسه محصول آبشده: اول settings، بعد const.
|
||||
* مقدار settings میتواند id عددی (مثل 13) یا reading_method (مثل estjt_...) باشد.
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
-- ============================================================================
|
||||
-- کلید main_wallet_products — اتصال محصولات به کیف اصلی (gold)
|
||||
--
|
||||
-- محصولاتی که id آنها در این کلید است، دارایی جدا ندارند؛
|
||||
-- موجودیشان همان gold کیف اصلی کاربر است (ساختار قدیم تکآبشده).
|
||||
-- اگر چند id باشد، همگی یک موجودی مشترک (کیف اصلی) دارند و در صفحه
|
||||
-- داراییها فقط یک کارت (محصول اولِ لیست) ساخته میشود.
|
||||
--
|
||||
-- مقدار: idها با کاما (مثل «13,25») یا آرایه JSON (مثل «[13,25]»)
|
||||
-- خالی/غایب = رفتار قبلی بدون هیچ تغییری (بورس مس و پروژههای چندکیفه)
|
||||
--
|
||||
-- نمونه اجرا برای گلد علی:
|
||||
-- UPDATE `settings` SET `value` = '13,25' WHERE `key` = 'main_wallet_products';
|
||||
-- ============================================================================
|
||||
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`)
|
||||
SELECT 'main_wallet_products', '', 'محصولات متصل به کیف اصلی', 0, 1,
|
||||
'idهای محصول با کاما (مثل 13,25). موجودی این محصولات = gold کیف اصلی. خالی = غیرفعال'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'main_wallet_products' LIMIT 1);
|
||||
|
||||
-- اگر کلید از قبل وجود دارد، قابل ادیت نبودنش تضمین شود
|
||||
UPDATE `settings` SET `can_edit` = 0 WHERE `key` = 'main_wallet_products';
|
||||
@@ -294,6 +294,30 @@ AND NOT EXISTS (
|
||||
SELECT 1 FROM `settings` WHERE `key` = 'unit' LIMIT 1
|
||||
);
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- settings — main_wallet_products: محصولات متصل به کیف اصلی (غیرقابل ادیت در پنل)
|
||||
-- موجودی این محصولات = gold کیف اصلی. خالی = غیرفعال (رفتار پیشفرض چندکیفه)
|
||||
-- مثال گلد علی: UPDATE settings SET value='13,25' WHERE `key`='main_wallet_products';
|
||||
-- ---------------------------------------------------------------------------
|
||||
INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`)
|
||||
SELECT
|
||||
'main_wallet_products',
|
||||
'',
|
||||
'محصولات متصل به کیف اصلی',
|
||||
0,
|
||||
1,
|
||||
'idهای محصول با کاما (مثل 13,25). موجودی این محصولات = gold کیف اصلی. خالی = غیرفعال'
|
||||
FROM DUAL
|
||||
WHERE EXISTS (
|
||||
SELECT 1 FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'settings'
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM `settings` WHERE `key` = 'main_wallet_products' LIMIT 1
|
||||
);
|
||||
|
||||
UPDATE `settings` SET `can_edit` = 0 WHERE `key` = 'main_wallet_products';
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- پایان — برای بورسمس (اختیاری، جدا اجرا کنید):
|
||||
-- UPDATE `settings` SET `value` = 'کیلوگرم' WHERE `key` = 'unit';
|
||||
|
||||
Reference in New Issue
Block a user