mirror of
https://github.com/wasrusgen/wasrusgen1-crm.git
synced 2026-06-03 15:04:47 +00:00
feat(платежи): автозадачи-напоминания о сроках оплаты этапов
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
066a628695
commit
2fc91433da
@ -195,7 +195,7 @@ async function newClient(){
|
||||
function setView(v){view=v;current=null;document.getElementById("nav-dash").classList.toggle("active",v==="dashboard");document.getElementById("nav-pipe").classList.toggle("active",v==="pipeline");renderClientList();render();}
|
||||
async function openClient(token){
|
||||
current=token;view="client";mainTab="deal";editPayIdx=-1;document.querySelectorAll(".nav-item").forEach(n=>n.classList.remove("active"));
|
||||
const r=await fetch(`${API}/api/project/${token}`);state=await r.json();renderClientList();render();
|
||||
const r=await fetch(`${API}/api/project/${token}`);state=await r.json();renderClientList();render();syncPaymentReminders();
|
||||
}
|
||||
function render(){
|
||||
if(view==="dashboard")renderDashboard();
|
||||
@ -451,14 +451,34 @@ function editStagePrice(k){
|
||||
state.crm.stage_prices=state.crm.stage_prices||{};
|
||||
state.crm.stage_prices[k]=n;
|
||||
// сумму сделки НЕ трогаем — разница показывается как «нераспределено»
|
||||
saveEstimate();renderClient();
|
||||
saveEstimate();syncPaymentReminders();renderClient();
|
||||
}
|
||||
// ── Сроки этапов (плановая дата оплаты) ──
|
||||
function getStageDue(){return (state.crm&&state.crm.stage_due)||{};}
|
||||
function setStageDue(k,v){
|
||||
state.crm=state.crm||{};state.crm.stage_due=state.crm.stage_due||{};
|
||||
if(v)state.crm.stage_due[k]=v; else delete state.crm.stage_due[k];
|
||||
fetch(`${API}/api/project/crm`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:current,stage_due:state.crm.stage_due})}).then(loadProjects);
|
||||
fetch(`${API}/api/project/crm`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:current,stage_due:state.crm.stage_due})})
|
||||
.then(()=>{syncPaymentReminders();return loadProjects();});
|
||||
}
|
||||
// ── Автозадачи-напоминания о сроках оплаты этапов (идемпотентно) ──
|
||||
function syncPaymentReminders(){
|
||||
if(!state||!state.crm)return;
|
||||
const due=getStageDue(), sp=getStagePrices()||{}, pays=getStagePays();
|
||||
state.tasks=state.tasks||[];
|
||||
let changed=false;
|
||||
CLIENT_STAGES.forEach(s=>{
|
||||
const marker='pay_'+s.key;
|
||||
const need=due[s.key]&&(sp[s.key]||0)>0&&!pays[s.key];
|
||||
const idx=state.tasks.findIndex(t=>t.auto===marker);
|
||||
if(need){
|
||||
const text=`💳 Получить оплату за «${s.name}» — ${money(sp[s.key])}`;
|
||||
if(idx<0){state.tasks.push({text,due:due[s.key],done:false,auto:marker});changed=true;}
|
||||
else if(state.tasks[idx].due!==due[s.key]||state.tasks[idx].text!==text||state.tasks[idx].done){
|
||||
state.tasks[idx].due=due[s.key];state.tasks[idx].text=text;state.tasks[idx].done=false;changed=true;}
|
||||
} else if(idx>=0){state.tasks.splice(idx,1);changed=true;}
|
||||
});
|
||||
if(changed)saveTasks();
|
||||
}
|
||||
// ── Подогнать сумму сделки под смету ──
|
||||
function alignDealToEstimate(){
|
||||
@ -516,7 +536,7 @@ async function confirmStagePay(k){
|
||||
fetch(`${API}/api/project/crm`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:current,stage_payments:pays,payments:state.crm.payments})}),
|
||||
loadProjects()
|
||||
]);
|
||||
renderClient();
|
||||
syncPaymentReminders();renderClient();
|
||||
}
|
||||
async function unStagePay(k){
|
||||
const pays=getStagePays();if(!pays[k])return;
|
||||
@ -527,7 +547,7 @@ async function unStagePay(k){
|
||||
for(let i=arr.length-1;i>=0;i--){if(arr[i].stage===k){arr.splice(i,1);break;}}
|
||||
state.crm.payments=arr;
|
||||
await fetch(`${API}/api/project/crm`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:current,stage_payments:pays,payments:arr})});
|
||||
await loadProjects();renderClient();
|
||||
await loadProjects();syncPaymentReminders();renderClient();
|
||||
}
|
||||
function renderPaymentPlan(){
|
||||
const box=document.getElementById("planBox");if(!box)return;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user