fix reports
This commit is contained in:
+129
-76
@@ -15,104 +15,157 @@
|
|||||||
configReject = reject;
|
configReject = reject;
|
||||||
});
|
});
|
||||||
|
|
||||||
// API endpoint for config - you can change this URL
|
const VERSION_URL = 'https://abshode-service.montgit.ir/server/get_version';
|
||||||
// You can also set it via a data attribute: <script src="/config-loader.js" data-config-url="https://your-api.com/config"></script>
|
const CONFIG_URLS = [
|
||||||
//const scriptTag = document.currentScript || document.querySelector('script[src*="config-loader.js"]');
|
'https://nerkh.gold/get_user',
|
||||||
//const customUrl = scriptTag ? scriptTag.getAttribute('data-config-url') : null;
|
'https://abshode-service.montgit.ir/server/get_user'
|
||||||
const CONFIG_URL = 'https://nerkh.gold/get_user' //customUrl || window.location.origin + '/api/config';
|
];
|
||||||
|
const CONFIG_SUCCESS_URL_KEY = 'CONFIG_Success_URL';
|
||||||
|
|
||||||
// Timeout to ensure main.ts loads even if config fails (5 seconds)
|
// Timeout to ensure main.ts loads even if config fails
|
||||||
const CONFIG_TIMEOUT = 5000;
|
const CONFIG_TIMEOUT = 12000;
|
||||||
let configTimeoutId;
|
let configTimeoutId;
|
||||||
let mainScriptLoaded = false;
|
let mainScriptLoaded = false;
|
||||||
|
|
||||||
// Fetch config from server
|
function getProtocol() {
|
||||||
async function loadConfig() {
|
return window.location.protocol === 'https:' ? 'https:' : 'http:';
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortConfigUrls(urls) {
|
||||||
|
const lastSuccessUrl = localStorage.getItem(CONFIG_SUCCESS_URL_KEY);
|
||||||
|
|
||||||
|
return [...urls].sort((a, b) => {
|
||||||
|
if (a === lastSuccessUrl) return -1;
|
||||||
|
if (b === lastSuccessUrl) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchJson(url, timeout = 3500) {
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timeoutId = window.setTimeout(() => controller.abort(), timeout);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(CONFIG_URL, {
|
const response = await fetch(url, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
Accept: 'application/json'
|
||||||
},
|
},
|
||||||
cache: 'no-cache'
|
cache: 'no-store',
|
||||||
|
signal: controller.signal
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to fetch config: ' + response.status);
|
throw new Error('Request failed: ' + response.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if response is actually JSON
|
const contentType = response.headers.get('content-type') || '';
|
||||||
const contentType = response.headers.get('content-type');
|
|
||||||
if (!contentType || !contentType.includes('application/json')) {
|
if (!contentType.includes('application/json')) {
|
||||||
const text = await response.text();
|
const text = await response.text();
|
||||||
throw new Error('Response is not JSON. Received: ' + text.substring(0, 100));
|
throw new Error('Response is not JSON. Received: ' + text.substring(0, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = await response.json();
|
return await response.json();
|
||||||
|
} finally {
|
||||||
|
window.clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Store config in window object
|
async function loadVersion() {
|
||||||
window.__APP_CONFIG__ = config;
|
try {
|
||||||
window.__CONFIG_READY__ = true;
|
await fetchJson(VERSION_URL, 3500);
|
||||||
if (config?.user?.name_fa) {
|
console.log('Version loaded from:', VERSION_URL);
|
||||||
document.title = 'پنل مدیریت '+ '-'+config.user.name_fa;
|
|
||||||
}
|
|
||||||
// ---------- Dynamic Favicon ----------
|
|
||||||
if (config?.user?.avatar) {
|
|
||||||
const faviconUrl = config.user.avatar;
|
|
||||||
|
|
||||||
// remove existing favicon(s)
|
|
||||||
const existingIcons = document.querySelectorAll('link[rel*="icon"]');
|
|
||||||
existingIcons.forEach(icon => icon.remove());
|
|
||||||
|
|
||||||
// create new favicon
|
|
||||||
const link = document.createElement('link');
|
|
||||||
link.rel = 'icon';
|
|
||||||
link.type = 'image/png'; // یا image/x-icon
|
|
||||||
link.href = faviconUrl + '?v=' + Date.now();
|
|
||||||
|
|
||||||
document.head.appendChild(link);
|
|
||||||
}
|
|
||||||
// Resolve the promise
|
|
||||||
if (configResolve) {
|
|
||||||
configResolve(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dispatch custom event to notify that config is ready
|
|
||||||
window.dispatchEvent(new CustomEvent('configReady', { detail: config }));
|
|
||||||
|
|
||||||
console.log('Config loaded successfully:', config);
|
|
||||||
|
|
||||||
// Clear timeout if config loaded successfully
|
|
||||||
if (configTimeoutId) {
|
|
||||||
clearTimeout(configTimeoutId);
|
|
||||||
configTimeoutId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load main.ts after config is ready
|
|
||||||
loadMainScript();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Config loader: Could not fetch config from', CONFIG_URL);
|
console.warn('Version check failed from', VERSION_URL, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchConfig() {
|
||||||
|
const protocol = getProtocol();
|
||||||
|
const urls = sortConfigUrls(
|
||||||
|
CONFIG_URLS.map((url) => url.replace(/^https?:/, protocol))
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let index = 0; index < urls.length; index++) {
|
||||||
|
const url = urls[index];
|
||||||
|
const timeout = index === urls.length - 1 ? 5000 : 3500;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const config = await fetchJson(url, timeout);
|
||||||
|
|
||||||
|
if (!config || typeof config !== 'object') {
|
||||||
|
throw new Error('Config response is invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(CONFIG_SUCCESS_URL_KEY, url);
|
||||||
|
return { config, url };
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Config failed from', url, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('Cannot load config from any server');
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyConfig(config) {
|
||||||
|
window.__APP_CONFIG__ = config;
|
||||||
|
window.__CONFIG_READY__ = true;
|
||||||
|
|
||||||
|
if (config?.user?.name_fa) {
|
||||||
|
document.title = 'پنل مدیریت ' + '-' + config.user.name_fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config?.user?.avatar) {
|
||||||
|
const faviconUrl = config.user.avatar;
|
||||||
|
const existingIcons = document.querySelectorAll('link[rel*="icon"]');
|
||||||
|
existingIcons.forEach((icon) => icon.remove());
|
||||||
|
|
||||||
|
const link = document.createElement('link');
|
||||||
|
link.rel = 'icon';
|
||||||
|
link.type = 'image/png';
|
||||||
|
link.href = faviconUrl + '?v=' + Date.now();
|
||||||
|
document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishConfigLoad(config, error) {
|
||||||
|
if (configResolve) {
|
||||||
|
configResolve(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
window.dispatchEvent(new CustomEvent('configError', { detail: error }));
|
||||||
|
} else {
|
||||||
|
window.dispatchEvent(new CustomEvent('configReady', { detail: config }));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configTimeoutId) {
|
||||||
|
clearTimeout(configTimeoutId);
|
||||||
|
configTimeoutId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMainScript();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch config from server
|
||||||
|
async function loadConfig() {
|
||||||
|
try {
|
||||||
|
await loadVersion();
|
||||||
|
|
||||||
|
const { config, url } = await fetchConfig();
|
||||||
|
applyConfig(config);
|
||||||
|
|
||||||
|
console.log('Config loaded successfully from', url, config);
|
||||||
|
finishConfigLoad(config);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Config loader: Could not fetch config from any endpoint');
|
||||||
console.warn('Error details:', error.message);
|
console.warn('Error details:', error.message);
|
||||||
console.warn('This is normal if the endpoint does not exist yet. App will continue with empty config.');
|
console.warn('App will continue with empty config.');
|
||||||
// Set default empty config on error
|
|
||||||
window.__APP_CONFIG__ = {};
|
window.__APP_CONFIG__ = {};
|
||||||
window.__CONFIG_READY__ = true;
|
window.__CONFIG_READY__ = true;
|
||||||
|
finishConfigLoad({}, error);
|
||||||
// Resolve the promise even on error (with empty config)
|
|
||||||
if (configResolve) {
|
|
||||||
configResolve({});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.dispatchEvent(new CustomEvent('configError', { detail: error }));
|
|
||||||
|
|
||||||
// Clear timeout if error occurred
|
|
||||||
if (configTimeoutId) {
|
|
||||||
clearTimeout(configTimeoutId);
|
|
||||||
configTimeoutId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load main.ts even on error (with empty config)
|
|
||||||
loadMainScript();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,15 +62,28 @@
|
|||||||
{{ row.sts_str || '-' }}
|
{{ row.sts_str || '-' }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
|
<span
|
||||||
|
class="inline-flex rounded-lg border px-2 py-0.5 text-xs font-600"
|
||||||
|
:class="typeTagClass(row)"
|
||||||
|
>
|
||||||
|
{{ typeLabel(row) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<MobileStatCard bordered variant="danger" label="مقدار (ریال)" :value="usePrice(row.cash ?? 0, true, '')">
|
<MobileStatCard
|
||||||
|
bordered
|
||||||
|
:variant="amountVariant(row)"
|
||||||
|
label="مقدار"
|
||||||
|
:value="amountLabel(row)"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<BaseIcon icon="vuesax-linear:empty-wallet" size="18" color="#dc2626" />
|
<BaseIcon
|
||||||
</template>
|
:icon="isMoneyWithdraw(row) ? 'vuesax-linear:empty-wallet' : 'vuesax-linear:coin'"
|
||||||
</MobileStatCard>
|
size="18"
|
||||||
<MobileStatCard bordered variant="warning" :label="metalLabel.goldUnit()" :value="goldLabel(row)">
|
:color="amountIconColor(row)"
|
||||||
<template #prefix>
|
/>
|
||||||
<BaseIcon icon="vuesax-linear:coin" size="18" color="#b45309" />
|
|
||||||
</template>
|
</template>
|
||||||
</MobileStatCard>
|
</MobileStatCard>
|
||||||
</div>
|
</div>
|
||||||
@@ -104,10 +117,14 @@ import MobileInfoGrid from '@/components/mobile/MobileInfoGrid.vue'
|
|||||||
import MobileSheetHeader from '@/components/mobile/MobileSheetHeader.vue'
|
import MobileSheetHeader from '@/components/mobile/MobileSheetHeader.vue'
|
||||||
import MobileStatCard from '@/components/mobile/MobileStatCard.vue'
|
import MobileStatCard from '@/components/mobile/MobileStatCard.vue'
|
||||||
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||||
|
import {
|
||||||
|
formatWithdrawAmountDisplay,
|
||||||
|
isMoneyWithdraw,
|
||||||
|
withdrawAmountValue,
|
||||||
|
withdrawTypeLabel
|
||||||
|
} from '@/pages/menuPages/withdraw/utils/withdrawDisplay'
|
||||||
import { isMobile } from '@core/utils/is'
|
import { isMobile } from '@core/utils/is'
|
||||||
import { toJalali } from '@core/utils/useDataTime'
|
import { toJalali } from '@core/utils/useDataTime'
|
||||||
import { usePrice } from '@core/utils/usePrice'
|
|
||||||
import { metalLabel } from '@/utils/adminMetalLabels'
|
|
||||||
import { toNumber } from 'lodash'
|
import { toNumber } from 'lodash'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
@@ -155,8 +172,36 @@ function noteLabel(row: Withdraw) {
|
|||||||
return String(row.note)
|
return String(row.note)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goldLabel(row: Withdraw) {
|
function typeLabel(row: Withdraw) {
|
||||||
if (row.gold == null) return '-'
|
return withdrawTypeLabel(row)
|
||||||
return String(row.gold)
|
}
|
||||||
|
|
||||||
|
function typeTagClass(row: Withdraw) {
|
||||||
|
if (!isMoneyWithdraw(row)) {
|
||||||
|
return 'border-amber-300 bg-amber-50 text-amber-700'
|
||||||
|
}
|
||||||
|
return withdrawAmountValue(row) > 0
|
||||||
|
? 'border-green-300 bg-green-50 text-green-700'
|
||||||
|
: withdrawAmountValue(row) < 0
|
||||||
|
? 'border-red-300 bg-red-50 text-red-700'
|
||||||
|
: 'border-gray-300 bg-gray-50 text-gray-700'
|
||||||
|
}
|
||||||
|
|
||||||
|
function amountLabel(row: Withdraw) {
|
||||||
|
return formatWithdrawAmountDisplay(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
function amountVariant(row: Withdraw) {
|
||||||
|
const value = withdrawAmountValue(row)
|
||||||
|
if (value > 0) return 'success'
|
||||||
|
if (value < 0) return 'danger'
|
||||||
|
return 'warning'
|
||||||
|
}
|
||||||
|
|
||||||
|
function amountIconColor(row: Withdraw) {
|
||||||
|
const value = withdrawAmountValue(row)
|
||||||
|
if (value > 0) return '#15803d'
|
||||||
|
if (value < 0) return '#dc2626'
|
||||||
|
return '#b45309'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<div class="flex items-center justify-between gap-2 text-xs">
|
<div class="flex items-center justify-between gap-2 text-xs">
|
||||||
<span class="truncate text-gray-600">{{ noteLabel }}</span>
|
<span class="truncate text-gray-600">{{ noteLabel }}</span>
|
||||||
<span class="shrink-0 font-700 text-red-600">{{ cashLabel }}</span>
|
<span class="shrink-0 font-700" :class="amountClass">{{ amountLabel }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MobileCard>
|
</MobileCard>
|
||||||
@@ -18,7 +18,10 @@
|
|||||||
import type { Withdraw } from '@/model/wallet'
|
import type { Withdraw } from '@/model/wallet'
|
||||||
import MobileCard from '@/components/mobile/MobileCard.vue'
|
import MobileCard from '@/components/mobile/MobileCard.vue'
|
||||||
import { toJalaliNoTime } from '@core/utils/useDataTime'
|
import { toJalaliNoTime } from '@core/utils/useDataTime'
|
||||||
import { usePrice } from '@core/utils/usePrice'
|
import {
|
||||||
|
formatWithdrawAmountDisplay,
|
||||||
|
withdrawAmountValue
|
||||||
|
} from '@/pages/menuPages/withdraw/utils/withdrawDisplay'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: Withdraw
|
item: Withdraw
|
||||||
@@ -35,5 +38,11 @@ const noteLabel = computed(() => {
|
|||||||
|
|
||||||
const customerName = computed(() => props.item.customer?.name || '-')
|
const customerName = computed(() => props.item.customer?.name || '-')
|
||||||
const dateLabel = computed(() => (props.item.created_at ? toJalaliNoTime(props.item.created_at) : '-'))
|
const dateLabel = computed(() => (props.item.created_at ? toJalaliNoTime(props.item.created_at) : '-'))
|
||||||
const cashLabel = computed(() => usePrice(props.item.cash ?? 0, true, ''))
|
const amountLabel = computed(() => formatWithdrawAmountDisplay(props.item))
|
||||||
|
const amountClass = computed(() => {
|
||||||
|
const value = withdrawAmountValue(props.item)
|
||||||
|
if (value > 0) return 'text-green-600'
|
||||||
|
if (value < 0) return 'text-red-600'
|
||||||
|
return 'text-gray-600'
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||||
import { toJalali, toJalaliNoTime, toTime } from '@core/utils/useDataTime'
|
import { toJalali, toJalaliNoTime, toTime } from '@core/utils/useDataTime'
|
||||||
import CustomTag from '@/components/CustomTag.vue'
|
import CustomTag from '@/components/CustomTag.vue'
|
||||||
import { usePrice } from '@core/utils/usePrice'
|
|
||||||
import WithdrawStatus from "@/pages/menuPages/withdraw/components/WithdrawStatus.vue";
|
import WithdrawStatus from "@/pages/menuPages/withdraw/components/WithdrawStatus.vue";
|
||||||
import { metalLabel } from '@/utils/adminMetalLabels'
|
import {
|
||||||
|
formatWithdrawAmountDisplay,
|
||||||
|
isMoneyWithdraw,
|
||||||
|
withdrawAmountColorClass,
|
||||||
|
withdrawTypeLabel
|
||||||
|
} from '@/pages/menuPages/withdraw/utils/withdrawDisplay'
|
||||||
/*import BudgetSelect from '@/components/BudgetSelect.vue'
|
/*import BudgetSelect from '@/components/BudgetSelect.vue'
|
||||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||||
import type { FilterSelect } from '@/model/filterSelect'
|
import type { FilterSelect } from '@/model/filterSelect'
|
||||||
@@ -71,23 +75,43 @@ export function getWithdrawColumns(): BaseTableColumn[] {
|
|||||||
type: 'Text'
|
type: 'Text'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'مقدار (ریال)',
|
title: 'نوع',
|
||||||
dataIndex: 'cash',
|
dataIndex: 'asset_type',
|
||||||
key: 'cash',
|
key: 'asset_type',
|
||||||
type: 'Number',
|
filterable: false,
|
||||||
|
sortable: false,
|
||||||
customRender: ({ record }) => {
|
customRender: ({ record }) => {
|
||||||
|
const label = withdrawTypeLabel(record)
|
||||||
|
if (label === '-') {
|
||||||
|
return <div class="flex justify-center px-6">-</div>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<div class={'font-bold px-6 text-red'}>{usePrice(record.cash ?? 0, true, '')}</div>
|
<CustomTag
|
||||||
|
textColor={isMoneyWithdraw(record) ? '#25855A' : '#ca8a04'}
|
||||||
|
bgColor={isMoneyWithdraw(record) ? '#E3F4E9' : '#fef3c7'}
|
||||||
|
class="font-bold px-6"
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</CustomTag>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: metalLabel.goldUnit(),
|
title: 'مقدار',
|
||||||
dataIndex: 'gold',
|
dataIndex: 'amount',
|
||||||
key: 'gold',
|
key: 'amount',
|
||||||
type: 'Number',
|
type: 'Number',
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
const colorClass = withdrawAmountColorClass(record)
|
||||||
|
return (
|
||||||
|
<div class="flex justify-center">
|
||||||
|
<div class={`font-bold px-6 ${colorClass}`}>{formatWithdrawAmountDisplay(record)}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'شماره کارت',
|
title: 'شماره کارت',
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import type { Withdraw } from '@/model/wallet'
|
||||||
|
import { metalLabel } from '@/utils/adminMetalLabels'
|
||||||
|
import { getMainMetal } from '@/utils/metalLabels'
|
||||||
|
import {
|
||||||
|
formatMetalDisplayValue,
|
||||||
|
METAL_ID_COPPER,
|
||||||
|
METAL_ID_GOLD,
|
||||||
|
METAL_ID_SILVER,
|
||||||
|
metalDisplayUnit
|
||||||
|
} from '@/utils/metalWeight'
|
||||||
|
import { usePrice } from '@core/utils/usePrice'
|
||||||
|
|
||||||
|
export function resolveWithdrawMetalId(): number {
|
||||||
|
const main = getMainMetal()
|
||||||
|
if (main.includes('مس')) return METAL_ID_COPPER
|
||||||
|
if (main.includes('نقره')) return METAL_ID_SILVER
|
||||||
|
return METAL_ID_GOLD
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMoneyWithdraw(record: Pick<Withdraw, 'cash' | 'gold'>): boolean {
|
||||||
|
const gold = Math.abs(Number(record.gold ?? 0))
|
||||||
|
if (gold > 0) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
export function withdrawTypeLabel(record: Pick<Withdraw, 'cash' | 'gold'>): string {
|
||||||
|
if (!isMoneyWithdraw(record)) {
|
||||||
|
return metalLabel.goldUnit()
|
||||||
|
}
|
||||||
|
|
||||||
|
const cash = Math.abs(Number(record.cash ?? 0))
|
||||||
|
return cash > 0 ? 'پول' : '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function withdrawAmountValue(record: Pick<Withdraw, 'cash' | 'gold'>): number {
|
||||||
|
if (isMoneyWithdraw(record)) {
|
||||||
|
return Number(record.cash ?? 0)
|
||||||
|
}
|
||||||
|
return Number(record.gold ?? 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatWithdrawAmountDisplay(record: Pick<Withdraw, 'cash' | 'gold'>): string {
|
||||||
|
const value = withdrawAmountValue(record)
|
||||||
|
|
||||||
|
if (isMoneyWithdraw(record)) {
|
||||||
|
if (!value) return `0 ریال`
|
||||||
|
const formatted = usePrice(Math.abs(value), true, '')
|
||||||
|
return value > 0 ? `${formatted} ریال` : `-${formatted} ریال`
|
||||||
|
}
|
||||||
|
|
||||||
|
const metalId = resolveWithdrawMetalId()
|
||||||
|
const unit = metalDisplayUnit(metalId)
|
||||||
|
if (!value) return `0 ${unit}`
|
||||||
|
|
||||||
|
const formatted = formatMetalDisplayValue(Math.abs(value), metalId)
|
||||||
|
return value > 0 ? formatted : `-${formatted}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function withdrawAmountColorClass(record: Pick<Withdraw, 'cash' | 'gold'>): string {
|
||||||
|
const value = withdrawAmountValue(record)
|
||||||
|
if (!value) return ''
|
||||||
|
return value > 0 ? 'text-green' : 'text-red'
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user