mirror of
https://github.com/wasrusgen/wasrusgen1-crm.git
synced 2026-06-03 15:04:47 +00:00
ui: полное редактирование сметы — правка цены этапа, отмена оплаты, синхронизация с реестром
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
24bd0e29d5
commit
9b0d0af277
@ -499,6 +499,17 @@ async function confirmStagePay(k){
|
||||
]);
|
||||
renderClient();
|
||||
}
|
||||
async function unStagePay(k){
|
||||
const pays=getStagePays();if(!pays[k])return;
|
||||
if(!confirm('Отменить оплату этапа «'+CLIENT_STAGES.find(s=>s.key===k).name+'»? Связанный платёж удалится из реестра.'))return;
|
||||
delete pays[k];
|
||||
state.crm.stage_payments=pays;
|
||||
const arr=state.crm.payments||[];
|
||||
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();
|
||||
}
|
||||
function renderPaymentPlan(){
|
||||
const box=document.getElementById("planBox");if(!box)return;
|
||||
const billing=(state.crm&&state.crm.billing_type)||"paid";
|
||||
@ -532,7 +543,7 @@ function renderPaymentPlan(){
|
||||
<span style="font-size:11px;font-weight:700;color:var(--primary);background:#ECFDF5;padding:3px 9px;border-radius:6px">${CX_SHORT[cx]}</span>
|
||||
<button class="cp-btn cp-r" style="padding:4px 9px;margin-left:auto" onclick="buildEstimate()">↻ Пересчитать</button>
|
||||
</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-bottom:12px">Получено <b style="color:var(--primary)">${money(paidTotal)}</b> из ${money(total)} · нажмите цену чтобы изменить</div>
|
||||
<div style="font-size:11px;color:var(--muted);margin-bottom:12px">Получено <b style="color:var(--primary)">${money(paidTotal)}</b> из ${money(total)} · <b>✎</b> — изменить цену · <b style="color:#DC2626">↺</b> — отменить оплату · «↻ Пересчитать» сбрасывает к ставкам</div>
|
||||
${CLIENT_STAGES.map(s=>{
|
||||
const done=stageIsDone(s.key);
|
||||
const paid=pays[s.key];
|
||||
@ -562,7 +573,7 @@ function renderPaymentPlan(){
|
||||
<div style="font-weight:700;font-size:13px;color:${done||isFree?'var(--text)':'#9CA3AF'}">${s.name}${badge}</div>
|
||||
${sub}
|
||||
</div>
|
||||
${action}
|
||||
<div style="display:flex;align-items:center;gap:7px">${action}<span onclick="event.stopPropagation();editStagePrice('${s.key}')" title="Изменить цену этапа" style="cursor:pointer;color:#9CA3AF;font-size:14px;line-height:1">✎</span>${paid?`<span onclick="event.stopPropagation();unStagePay('${s.key}')" title="Отменить оплату" style="cursor:pointer;color:#DC2626;font-size:14px;line-height:1">↺</span>`:''}</div>
|
||||
</div>`;
|
||||
}).join("")}
|
||||
<div style="display:flex;align-items:center;gap:10px;padding:12px 0 2px;border-top:2px solid var(--bg);margin-top:4px">
|
||||
@ -649,7 +660,15 @@ function addPayment(){
|
||||
}
|
||||
savePayments();renderClient();
|
||||
}
|
||||
function delPayment(i){state.crm.payments.splice(i,1);savePayments();renderClient();}
|
||||
function delPayment(i){
|
||||
const removed=state.crm.payments[i];
|
||||
state.crm.payments.splice(i,1);
|
||||
if(removed&&removed.stage&&state.crm.stage_payments){
|
||||
const stillPaid=state.crm.payments.some(p=>p.stage===removed.stage);
|
||||
if(!stillPaid)delete state.crm.stage_payments[removed.stage];
|
||||
}
|
||||
savePayments();renderClient();
|
||||
}
|
||||
function remindBalance(left){
|
||||
const due=new Date(Date.now()+7*864e5).toISOString().slice(0,10);
|
||||
state.tasks=state.tasks||[];state.tasks.push({text:`Получить остаток ${money(left)} от ${state.client_name||'клиента'}`,due,done:false});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user