WIP report. Added stats, sagas for calculation, formatting.
This commit is contained in:
@@ -29,7 +29,7 @@ export default function CloseDateDisplayMolecule({ jobId, close_date }) {
|
|||||||
return (
|
return (
|
||||||
<div onBlur={() => setEditMode(false)}>
|
<div onBlur={() => setEditMode(false)}>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
value={value.isValid() ? value : null}
|
value={value && value.isValid() ? value : null}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
{loading && <Spin size="small" />}
|
{loading && <Spin size="small" />}
|
||||||
@@ -38,7 +38,7 @@ export default function CloseDateDisplayMolecule({ jobId, close_date }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ cursor: "pointer" }} onClick={() => setEditMode(true)}>
|
<div style={{ cursor: "pointer" }} onClick={() => setEditMode(true)}>
|
||||||
{value.isValid() ? value.format("MM/DD/yyyy") : "No date set"}
|
{value && value.isValid() ? value.format("MM/DD/yyyy") : "No date set"}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export default function JobsSearchFieldsMolecule({ callSearchQuery }) {
|
|||||||
const handleFinish = (values) => {
|
const handleFinish = (values) => {
|
||||||
callSearchQuery({
|
callSearchQuery({
|
||||||
variables: {
|
variables: {
|
||||||
search: values.search,
|
search: values.search || "",
|
||||||
startDate: (values.dateRange && values.dateRange[0]) || null,
|
startDate: (values.dateRange && values.dateRange[0]) || null,
|
||||||
endDate: (values.dateRange && values.dateRange[1]) || null,
|
endDate: (values.dateRange && values.dateRange[1]) || null,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -53,10 +53,9 @@ export function JobsTargetsStatsMolecule({
|
|||||||
<Statistic
|
<Statistic
|
||||||
title="Current RPS %"
|
title="Current RPS %"
|
||||||
valueStyle={{
|
valueStyle={{
|
||||||
color:
|
color: selectedJobTargetPc > currentRpsPc ? "tomato" : "seagreen",
|
||||||
selectedJobTargetPc * 100 > currentRpsPc ? "tomato" : "seagreen",
|
|
||||||
}}
|
}}
|
||||||
value={currentRpsPc}
|
value={(currentRpsPc * 100).toFixed(1)}
|
||||||
suffix="%"
|
suffix="%"
|
||||||
/>
|
/>
|
||||||
<Statistic title="Current RPS $" value={currentRpsDollars.toFormat()} />
|
<Statistic title="Current RPS $" value={currentRpsDollars.toFormat()} />
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
import { Input, Table } from "antd";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import CurrencyFormatterAtom from "../../atoms/currency-formatter/currency-formatter.atom";
|
||||||
|
import IgnoreJobLine from "../../atoms/ignore-job-line/ignore-job-line.atom";
|
||||||
|
import partTypeConverterAtom from "../../atoms/part-type-converter/part-type-converter.atom";
|
||||||
|
import PriceDiffPcFormatterAtom from "../../atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom";
|
||||||
|
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import {
|
||||||
|
selectReportData,
|
||||||
|
selectReportLoading,
|
||||||
|
} from "../../../redux/reporting/reporting.selectors";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
reportingLoading: selectReportLoading,
|
||||||
|
reportData: selectReportData,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ReportingJobsListMolecule);
|
||||||
|
|
||||||
|
export function ReportingJobsListMolecule({ reportingLoading, reportData }) {
|
||||||
|
const [searchText, setSearchText] = useState("");
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "Claim No.",
|
||||||
|
dataIndex: "clm_no",
|
||||||
|
key: "clm_no",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Ins Co.",
|
||||||
|
dataIndex: "ins_co_nm",
|
||||||
|
key: "ins_co_nm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "First Name",
|
||||||
|
dataIndex: "ownr_fn",
|
||||||
|
key: "ownr_fn",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Last Name",
|
||||||
|
dataIndex: "ownr_ln",
|
||||||
|
key: "ownr_ln",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Vehicle",
|
||||||
|
dataIndex: "vehicle",
|
||||||
|
key: "vehicle",
|
||||||
|
render: (text, record) =>
|
||||||
|
`${record.v_model_yr} ${record.v_makedesc} ${record.v_model} (${
|
||||||
|
record.v_type
|
||||||
|
}) - ${record.group} @ ${
|
||||||
|
record.v_age === 1 ? `${record.v_age} year` : `${record.v_age} years`
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Database Price Sum",
|
||||||
|
dataIndex: "dbPriceSum",
|
||||||
|
key: "dbPriceSum",
|
||||||
|
render: (text, record) => record.dbPriceSum.toFormat(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Actual Price Sum ",
|
||||||
|
dataIndex: "actPriceSum",
|
||||||
|
key: "actPriceSum",
|
||||||
|
render: (text, record) => record.actPriceSum.toFormat(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Price Diff.",
|
||||||
|
dataIndex: "jobRpsDollars",
|
||||||
|
key: "jobRpsDollars",
|
||||||
|
render: (text, record) => (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: record.jobRpsPc > record.jobTarget ? "seagreen" : "tomato",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{`${record.jobRpsDollars.toFormat()} / ${record.expectedRpsDollars.toFormat()}`}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Price Diff. %",
|
||||||
|
dataIndex: "price_diff_pc",
|
||||||
|
key: "price_diff_pc",
|
||||||
|
render: (text, record) => (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: record.jobRpsPc > record.jobTarget ? "seagreen" : "tomato",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{`${(record.jobRpsPc * 100).toFixed(1)}% / ${(
|
||||||
|
record.jobTarget * 100
|
||||||
|
).toFixed(1)}%`}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const data =
|
||||||
|
searchText !== ""
|
||||||
|
? reportData.filter(
|
||||||
|
(j) =>
|
||||||
|
j.ownr_fn.toLowerCase().includes(searchText.toLowerCase()) ||
|
||||||
|
j.ownr_ln.toLowerCase().includes(searchText.toLowerCase()) ||
|
||||||
|
j.ownr_clm_no.toLowerCase().includes(searchText.toLowerCase())
|
||||||
|
)
|
||||||
|
: reportData;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
title={() => (
|
||||||
|
<Input.Search
|
||||||
|
placeholder="Search"
|
||||||
|
onSearch={(val) => {
|
||||||
|
setSearchText(val);
|
||||||
|
}}
|
||||||
|
enterButton
|
||||||
|
allowClear
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
loading={reportingLoading}
|
||||||
|
size="small"
|
||||||
|
pagination={false}
|
||||||
|
dataSource={data}
|
||||||
|
scroll={{
|
||||||
|
x: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { Skeleton, Statistic } from "antd";
|
||||||
|
import React, { useCallback } from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectSelectedJobTargetPc } from "../../../redux/application/application.selectors";
|
||||||
|
import {
|
||||||
|
selectReportLoading,
|
||||||
|
selectScorecard,
|
||||||
|
} from "../../../redux/reporting/reporting.selectors";
|
||||||
|
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
reportingLoading: selectReportLoading,
|
||||||
|
scoreCard: selectScorecard,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ReportingTotalsStatsMolecule);
|
||||||
|
|
||||||
|
export function ReportingTotalsStatsMolecule({ reportingLoading, scoreCard }) {
|
||||||
|
if (reportingLoading) return <Skeleton active />;
|
||||||
|
if (!scoreCard)
|
||||||
|
return <ErrorResultAtom title="Error displaying score card data." />;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
marginTop: "1rem",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Statistic
|
||||||
|
title="RPS Total"
|
||||||
|
value={scoreCard.shopRpsTotalDollars.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title="RPS Expectation"
|
||||||
|
value={scoreCard.shopRpsExpectedDollars.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title="RPS Variance $"
|
||||||
|
valueStyle={{
|
||||||
|
color:
|
||||||
|
scoreCard.varianceDollars.getAmount() < 0 ? "tomato" : "seagreen",
|
||||||
|
}}
|
||||||
|
value={scoreCard.varianceDollars.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title="Current RPS %"
|
||||||
|
valueStyle={{
|
||||||
|
color:
|
||||||
|
scoreCard.currentRpsPc <= scoreCard.targetRpsPc
|
||||||
|
? "tomato"
|
||||||
|
: "seagreen",
|
||||||
|
}}
|
||||||
|
value={(scoreCard.currentRpsPc * 100).toFixed(1)}
|
||||||
|
suffix="%"
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title="Target RPS %"
|
||||||
|
value={(scoreCard.targetRpsPc * 100).toFixed(1)}
|
||||||
|
suffix="%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,10 +1,29 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectDates } from "../../../redux/reporting/reporting.selectors";
|
||||||
import ReportingDatesMolecule from "../../molecules/reporting-dates/reporting-dates.molecule";
|
import ReportingDatesMolecule from "../../molecules/reporting-dates/reporting-dates.molecule";
|
||||||
|
import ReportingJobsListMolecule from "../../molecules/reporting-jobs-list/reporting-jobs-list.molecule";
|
||||||
|
import ReportingTotalsStatsMolecule from "../../molecules/reporting-totals-stats/reporting-totals-stats.molecule";
|
||||||
|
|
||||||
export default function ReportingPage() {
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
dates: selectDates,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(ReportingPage);
|
||||||
|
|
||||||
|
export function ReportingPage({ dates }) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ReportingDatesMolecule />
|
<ReportingDatesMolecule />
|
||||||
|
{dates && dates.startDate && dates.endDate && (
|
||||||
|
<div>
|
||||||
|
<ReportingTotalsStatsMolecule />
|
||||||
|
<ReportingJobsListMolecule />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ export const REPORTING_GET_JOBS = gql`
|
|||||||
v_makedesc
|
v_makedesc
|
||||||
v_model
|
v_model
|
||||||
v_model_yr
|
v_model_yr
|
||||||
|
v_vin
|
||||||
|
v_type
|
||||||
joblines {
|
joblines {
|
||||||
act_price
|
act_price
|
||||||
db_price
|
db_price
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
import { all, call, takeLatest, select, put } from "redux-saga/effects";
|
import { all, call, takeLatest, select, put } from "redux-saga/effects";
|
||||||
import { calculateScorecard, setReportingData } from "./reporting.actions";
|
import {
|
||||||
|
calculateScorecard,
|
||||||
|
setReportingData,
|
||||||
|
setScoreCard,
|
||||||
|
} from "./reporting.actions";
|
||||||
import ReportingApplicationTypes from "./reporting.types";
|
import ReportingApplicationTypes from "./reporting.types";
|
||||||
import client from "../../graphql/GraphQLClient";
|
import client from "../../graphql/GraphQLClient";
|
||||||
import { REPORTING_GET_JOBS } from "../../graphql/reporting.queries";
|
import { REPORTING_GET_JOBS } from "../../graphql/reporting.queries";
|
||||||
|
import Dinero from "dinero.js";
|
||||||
|
import {
|
||||||
|
CalculateJobRpsDollars,
|
||||||
|
CalculateJobRpsPc,
|
||||||
|
} from "../../util/CalculateJobRps";
|
||||||
|
import GetJobTarget from "../../util/GetJobTarget";
|
||||||
|
|
||||||
const { log } = window;
|
const { log } = window;
|
||||||
|
|
||||||
export function* onQueryReportData() {
|
export function* onQueryReportData() {
|
||||||
@@ -20,7 +31,7 @@ export function* queryReportingData({ payload: { startDate, endDate } }) {
|
|||||||
log.error("Error fetching report data.", result.errors);
|
log.error("Error fetching report data.", result.errors);
|
||||||
yield put(setReportingData(null));
|
yield put(setReportingData(null));
|
||||||
} else {
|
} else {
|
||||||
yield put(setReportingData(result.data.jobs));
|
yield put(calculateScorecard(result.data.jobs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +42,7 @@ export function* onSetReportData() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
export function* handleSetReportData({ payload: jobs }) {
|
export function* handleSetReportData({ payload: jobs }) {
|
||||||
yield put(calculateScorecard(jobs));
|
// yield put(calculateScorecard(jobs));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function* onCalculateScoreCard() {
|
export function* onCalculateScoreCard() {
|
||||||
@@ -42,10 +53,70 @@ export function* onCalculateScoreCard() {
|
|||||||
}
|
}
|
||||||
export function* handleCalculateScoreCard({ payload: jobs }) {
|
export function* handleCalculateScoreCard({ payload: jobs }) {
|
||||||
console.log("jobs", jobs);
|
console.log("jobs", jobs);
|
||||||
// yield put(calculateScorecard(jobs));
|
const targets = yield select((state) => state.user.bodyshop.targets);
|
||||||
|
|
||||||
|
const scoreCard = {
|
||||||
|
shopRpsTotalDollars: Dinero(),
|
||||||
|
shopRpsExpectedDollars: Dinero(),
|
||||||
|
varianceDollars: null,
|
||||||
|
variancePc: 0,
|
||||||
|
allJobsSumDbPrice: Dinero(),
|
||||||
|
allJobsSumActPrice: Dinero(),
|
||||||
|
currentRpsPc: 0,
|
||||||
|
targetRpsPc: 0,
|
||||||
|
};
|
||||||
|
|
||||||
//Get the RPS on a per job basis.
|
//Get the RPS on a per job basis.
|
||||||
|
jobs = jobs.map((job) => {
|
||||||
|
const { actPriceSum, jobRpsDollars } = CalculateJobRpsDollars(job, true);
|
||||||
|
const { dbPriceSum, jobRpsPc } = CalculateJobRpsPc(
|
||||||
|
job,
|
||||||
|
jobRpsDollars,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const jobTarget = GetJobTarget(job.group, job.v_age, targets);
|
||||||
|
scoreCard.shopRpsTotalDollars = scoreCard.shopRpsTotalDollars.add(
|
||||||
|
jobRpsDollars
|
||||||
|
);
|
||||||
|
const expectedRpsDollars = dbPriceSum.percentage(jobTarget * 100);
|
||||||
|
scoreCard.shopRpsExpectedDollars = scoreCard.shopRpsExpectedDollars.add(
|
||||||
|
expectedRpsDollars
|
||||||
|
);
|
||||||
|
|
||||||
|
scoreCard.allJobsSumDbPrice = scoreCard.allJobsSumDbPrice.add(dbPriceSum);
|
||||||
|
scoreCard.allJobsSumActPrice = scoreCard.allJobsSumActPrice.add(
|
||||||
|
actPriceSum
|
||||||
|
);
|
||||||
|
|
||||||
|
//sum db price * percentage expected.
|
||||||
|
return {
|
||||||
|
...job,
|
||||||
|
actPriceSum,
|
||||||
|
jobRpsDollars,
|
||||||
|
dbPriceSum,
|
||||||
|
jobRpsPc,
|
||||||
|
jobTarget,
|
||||||
|
expectedRpsDollars,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
scoreCard.varianceDollars = scoreCard.shopRpsTotalDollars.subtract(
|
||||||
|
scoreCard.shopRpsExpectedDollars
|
||||||
|
);
|
||||||
|
|
||||||
|
scoreCard.variancePc =
|
||||||
|
scoreCard.varianceDollars.getAmount() /
|
||||||
|
scoreCard.shopRpsExpectedDollars.getAmount();
|
||||||
|
|
||||||
|
scoreCard.currentRpsPc =
|
||||||
|
scoreCard.shopRpsTotalDollars.getAmount() /
|
||||||
|
scoreCard.allJobsSumDbPrice.getAmount();
|
||||||
|
scoreCard.targetRpsPc =
|
||||||
|
scoreCard.shopRpsExpectedDollars.getAmount() /
|
||||||
|
scoreCard.allJobsSumDbPrice.getAmount();
|
||||||
|
//Set the data.
|
||||||
|
yield put(setScoreCard(scoreCard));
|
||||||
|
yield put(setReportingData(jobs));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function* reportingSagas() {
|
export function* reportingSagas() {
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
import Dinero from "dinero.js";
|
import Dinero from "dinero.js";
|
||||||
|
|
||||||
export function CalculateJobRpsDollars(job) {
|
export function CalculateJobRpsDollars(job, returnSumActPrice) {
|
||||||
if (!job) {
|
if (!job) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return job.joblines
|
let actPriceSum = Dinero();
|
||||||
|
const jobRpsDollars = job.joblines
|
||||||
.filter((j) => !j.ignore)
|
.filter((j) => !j.ignore)
|
||||||
.reduce((acc, val) => {
|
.reduce((acc, val) => {
|
||||||
|
actPriceSum = actPriceSum.add(
|
||||||
|
Dinero({ amount: Math.round((val.act_price || 0) * 100) })
|
||||||
|
);
|
||||||
if (val.price_diff > 0) {
|
if (val.price_diff > 0) {
|
||||||
return acc.add(
|
return acc.add(
|
||||||
Dinero({ amount: Math.round((val.price_diff || 0) * 100) })
|
Dinero({ amount: Math.round((val.price_diff || 0) * 100) })
|
||||||
@@ -15,9 +19,14 @@ export function CalculateJobRpsDollars(job) {
|
|||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
}, Dinero());
|
}, Dinero());
|
||||||
|
return returnSumActPrice ? { actPriceSum, jobRpsDollars } : jobRpsDollars;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CalculateJobRpsPc(job, currentRpsDollars) {
|
export function CalculateJobRpsPc(
|
||||||
|
job,
|
||||||
|
currentRpsDollars,
|
||||||
|
returnSumDbPrice = false
|
||||||
|
) {
|
||||||
//TODO Redo this to do total of db price - act price / db price
|
//TODO Redo this to do total of db price - act price / db price
|
||||||
if (!job) {
|
if (!job) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -25,7 +34,9 @@ export function CalculateJobRpsPc(job, currentRpsDollars) {
|
|||||||
const dbPriceSum = job.joblines
|
const dbPriceSum = job.joblines
|
||||||
.filter((j) => !j.ignore)
|
.filter((j) => !j.ignore)
|
||||||
.reduce((acc, val) => {
|
.reduce((acc, val) => {
|
||||||
return acc + val.db_price;
|
return acc.add(Dinero({ amount: Math.round((val.db_price || 0) * 100) }));
|
||||||
}, 0);
|
}, Dinero());
|
||||||
return (currentRpsDollars.getAmount() / dbPriceSum).toFixed(1);
|
|
||||||
|
const jobRpsPc = currentRpsDollars.getAmount() / dbPriceSum.getAmount();
|
||||||
|
return returnSumDbPrice ? { dbPriceSum, jobRpsPc } : jobRpsPc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ export default function GetJobTarget(group, v_age, targets) {
|
|||||||
const targetPc = targetsForGroup.filter(
|
const targetPc = targetsForGroup.filter(
|
||||||
(t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true)
|
(t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true)
|
||||||
);
|
);
|
||||||
if (targetPc.length === 0) return 100;
|
if (targetPc.length === 0) return 1;
|
||||||
else if (targetPc.length === 1) return targetPc[0].target;
|
else if (targetPc.length === 1) return targetPc[0].target;
|
||||||
else {
|
else {
|
||||||
return 100;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user