portfolio-edit: bought-on-date mode + historical lookup
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
58576a86fc
commit
84934827b8
1 changed files with 72 additions and 0 deletions
|
|
@ -176,4 +176,76 @@
|
||||||
addPosition();
|
addPosition();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ---- Cost mode toggle + historical lookup --------------------------
|
||||||
|
|
||||||
|
const dateField = document.getElementById('pf-add-date-field');
|
||||||
|
const dateInput = document.getElementById('pf-add-date');
|
||||||
|
const dateStatus = document.getElementById('pf-add-date-status');
|
||||||
|
const costInput = document.getElementById('pf-add-cost');
|
||||||
|
|
||||||
|
function onModeChange() {
|
||||||
|
const mode = document.querySelector(
|
||||||
|
'input[name="pf-cost-mode"]:checked'
|
||||||
|
).value;
|
||||||
|
if (mode === 'date') {
|
||||||
|
dateField.hidden = false;
|
||||||
|
costInput.readOnly = true;
|
||||||
|
costInput.placeholder = 'auto-filled from date';
|
||||||
|
} else {
|
||||||
|
dateField.hidden = true;
|
||||||
|
costInput.readOnly = false;
|
||||||
|
costInput.placeholder = '150.25';
|
||||||
|
setStatus(dateStatus, '', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('input[name="pf-cost-mode"]').forEach(r =>
|
||||||
|
r.addEventListener('change', onModeChange)
|
||||||
|
);
|
||||||
|
|
||||||
|
async function fetchHistorical() {
|
||||||
|
if (!validated) {
|
||||||
|
setStatus(dateStatus, 'enter a valid ticker first', 'err');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const d = dateInput.value;
|
||||||
|
if (!d) {
|
||||||
|
setStatus(dateStatus, '', '');
|
||||||
|
costInput.value = '';
|
||||||
|
updateSubmitState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setStatus(dateStatus, 'looking up…', 'pending');
|
||||||
|
try {
|
||||||
|
const url = '/api/ticker/historical?symbol=' +
|
||||||
|
encodeURIComponent(validated.symbol) +
|
||||||
|
'&date=' + encodeURIComponent(d);
|
||||||
|
const r = await fetch(url);
|
||||||
|
if (r.status === 400) {
|
||||||
|
const j = await r.json().catch(() => ({detail: 'invalid date'}));
|
||||||
|
setStatus(dateStatus, '✗ ' + (j.detail || 'invalid date'), 'err');
|
||||||
|
costInput.value = '';
|
||||||
|
updateSubmitState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const j = await r.json();
|
||||||
|
if (j.ok) {
|
||||||
|
costInput.value = j.close.toFixed(2);
|
||||||
|
const tag = (j.actual_date && j.actual_date !== d)
|
||||||
|
? '✓ from ' + j.actual_date
|
||||||
|
: '✓';
|
||||||
|
setStatus(dateStatus, tag, 'ok');
|
||||||
|
} else {
|
||||||
|
setStatus(dateStatus, '✗ ' + (j.error || 'no data'), 'err');
|
||||||
|
costInput.value = '';
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setStatus(dateStatus, '✗ couldn\'t fetch — try again', 'err');
|
||||||
|
costInput.value = '';
|
||||||
|
}
|
||||||
|
updateSubmitState();
|
||||||
|
}
|
||||||
|
|
||||||
|
dateInput.addEventListener('blur', fetchHistorical);
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue