PageSourceSearch

https://seodoon-church-admin.web.app/assets/JournalListPage-DS1fj_fd.js

js seodoon-church-admin.web.app collected 2026-10-03 12:37:28 UTC 14,764 bytes, 1 lines download raw bytes

1import{j as e}from"./vendor-data-Z5doMMu-.js";import{r as d}from"./vendor-react-zNM0AU50.js";import{u as G}from"./index-D1K3lVhu.js";import{accountService as p}from"./accountService-CnSilcbs.js";import{n as H,f as o}from"./financeConstants-CXKUiVP8.js";import{z as c,aa as E,c as K,g as Q,r as V,ad as W,f as Z,a4 as ee,aB as I,T as te,ax as se,ar as B,i as re}from"./vendor-ui-CW5bJ11U.js";import"./vendor-firebase-Da9KY1q_.js";import"./vendor-charts-08G1rM8P.js";function me(){const{user:i}=G(),u=(i==null?void 0:i.churchId)||"seodoon-church",[R,F]=d.useState([]),[w,O]=d.useState([]),[P,C]=d.useState(!0),[h,M]=d.useState(""),[f,$]=d.useState(null),[z,y]=d.useState(!1),[g,D]=d.useState({startDate:new Date(new Date().getFullYear(),new Date().getMonth(),1).toISOString().split("T")[0],endDate:new Date().toISOString().split("T")[0]}),[a,m]=d.useState({date:new Date().toISOString().split("T")[0],description:"",reference:"",entries:[{accountCode:"",accountName:"",debitAmount:0,creditAmount:0},{accountCode:"",accountName:"",debitAmount:0,creditAmount:0}]});d.useEffect(()=>{b()},[u,g]);const b=async()=>{try{C(!0);const[t,s]=await Promise.all([p.getJournals(u,{startDate:g.startDate,endDate:g.endDate}),p.getAccounts(u)]);F(t),O(s)}catch(t){console.error("데이터 로드 실패:",t),c.error("데이터를 불러오는데 실패했습니다")}finally{C(!1)}},Y=t=>{const s={draft:{icon:re,color:"bg-gray-100 text-gray-700",label:"초안"},posted:{icon:B,color:"bg-green-100 text-green-700",label:"전기완료"},reversed:{icon:I,color:"bg-red-100 text-red-700",label:"역분개"}},r=s[t]||s.draft,l=r.icon;return e.jsxs("span",{className:`inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium ${r.color}`,children:[e.jsx(l,{className:"w-3 h-3"}),r.label]})},A=()=>{let t=0,s=0;return a.entries.forEach(r=>{t+=r.debitAmount||0,s+=r.creditAmount||0}),{totalDebit:t,totalCredit:s,isBalanced:t===s&&t>0}},L=()=>{m(t=>({...t,entries:[...t.entries,{accountCode:"",accountName:"",debitAmount:0,creditAmount:0}]}))},U=t=>{if(a.entries.length<=2){c.error("최소 2개의 분개 항목이 필요합니다");return}m(s=>({...s,entries:s.entries.filter((r,l)=>l!==t)}))},N=(t,s,r)=>{m(l=>{const n=[...l.entries];if(s==="accountCode"){const x=w.find(v=>v.code===r);n[t]={...n[t],accountCode:r,accountName:(x==null?void 0:x.name)||""}}else n[t]={...n[t],[s]:r};return{...l,entries:n}})},X=async()=>{const{totalDebit:t,totalCredit:s,isBalanced:r}=A();if(!a.description.trim()){c.error("적요를 입력해주세요");return}if(!r){c.error(`차변(${o(t)})과 대변(${o(s)})이 일치하지 않습니다`);return}const l=a.entries.filter(n=>n.accountCode&&(n.debitAmount>0||n.creditAmount>0));if(l.length<2){c.error("최소 2개 이상의 유효한 분개 항목이 필요합니다");return}try{const n={date:a.date,fiscalYear:String(new Date(a.date).getFullYear()),description:a.description,reference:a.reference,totalDebit:t,totalCredit:s,status:"draft",entries:l.map((x,v)=>({lineNumber:v+1,accountCode:x.accountCode,accountName:x.accountName,debit:x.debitAmount,credit:x.creditAmount,description:a.description}))};await p.createJournal(u,n),c.success("분개가 등록되었습니다"),y(!1),S(),b()}catch(n){console.error("분개 등록 실패:",n),c.error("분개 등록에 실패했습니다")}},_=async t=>{if(t.status!=="draft"){c.error("초안 상태의 분개만 전기할 수 있습니다");return}try{await p.postJournal(u,t.id,(i==null?void 0:i.uid)||""),c.success("분개가 전기되었습니다"),b()}catch(s){console.error("분개 전기 실패:",s),c.error("분개 전기에 실패했습니다")}},q=async t=>{if(t.status!=="posted"){c.error("전기된 분개만 역분개할 수 있습니다");return}if(confirm("이 분개를 역분개하시겠습니까?"))try{const s=new Date().toISOString().split("T")[0];await p.reverseJournal(u,t.id,s,(i==null?void 0:i.uid)||""),c.success("역분개가 완료되었습니다"),b()}catch(s){console.error("역분개 실패:",s),c.error("역분개에 실패했습니다")}},S=()=>{m({date:new Date().toISOString().split("T")[0],description:"",reference:"",entries:[{accountCode:"",accountName:"",debitAmount:0,creditAmount:0},{accountCode:"",accountName:"",debitAmount:0,creditAmount:0}]})},k=R.filter(t=>{var s,r;return h===""||t.description.includes(h)||((s=t.journalNumber)==null?void 0:s.includes(h))||((r=t.reference)==null?void 0:r.includes(h))}),{totalDebit:J,totalCredit:T,isBalanced:j}=A();return P?e.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"})}):e.jsxs("div",{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"분개장"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"복식부기 분개를 관리합니다 (Pro 모드)"})]}),e.jsxs("button",{onClick:()=>y(!0),className:"flex items-center gap-2 px-4 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors",children:[e.jsx(E,{className:"w-4 h-4"}),"분개 등록"]})]}),e.jsx("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-4 mb-6",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{className:"w-4 h-4 text-gray-400"}),e.jsx("input",{type:"date",value:g.startDate,onChange:t=>D(s=>({...s,startDate:t.target.value})),className:"px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"}),e.jsx("span",{className:"text-gray-400",children:"~"}),e.jsx("input",{type:"date",value:g.endDate,onChange:t=>D(s=>({...s,endDate:t.target.value})),className:"px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"})]}),e.jsxs("div",{className:"flex-1 relative",children:[e.jsx(Q,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400"}),e.jsx("input",{type:"text",placeholder:"적요, 전표번호로 검색...",value:h,onChange:t=>M(t.target.value),className:"w-full pl-9 pr-4 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"})]})]})}),e.jsx("div",{className:"space-y-3",children:k.length===0?e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-12 text-center",children:[e.jsx(V,{className:"w-12 h-12 mx-auto text-gray-300 mb-4"}),e.jsx("p",{className:"text-gray-500",children:"등록된 분개가 없습니다"})]}):k.map(t=>{var s;return e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden",children:[e.jsxs("button",{onClick:()=>$(f===t.id?null:t.id),className:"w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors",children:[e.jsx("div",{className:"flex items-center gap-4",children:e.jsxs("div",{className:"text-left",children:[e.jsx("p",{className:"text-sm text-gray-500",children:H(t.date)}),e.jsx("p",{className:"font-medium text-gray-900",children:t.description}),t.journalNumber&&e.jsxs("p",{className:"text-xs text-gray-400",children:["#",t.journalNumber]})]})}),e.jsxs("div",{className:"flex items-center gap-4",children:[Y(t.status),e.jsxs("div",{className:"text-right",children:[e.jsx("p",{className:"text-sm text-gray-500",children:"차변/대변"}),e.jsx("p",{className:"font-medium text-gray-900 fin-num",children:o(t.totalDebit)})]}),f===t.id?e.jsx(W,{className:"w-5 h-5 text-gray-400"}):e.jsx(Z,{className:"w-5 h-5 text-gray-400"})]})]}),f===t.id&&e.jsxs("div",{className:"border-t border-gray-100 p-4",children:[e.jsxs("table",{className:"w-full mb-4",children:[e.jsx("thead",{className:"bg-gray-50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium text-gray-500",children:"계정코드"}),e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium text-gray-500",children:"계정명"}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium text-gray-500",children:"차변"}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium text-gray-500",children:"대변"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-100",children:(s=t.entries)==null?void 0:s.map((r,l)=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-3 py-2 font-mono text-sm",children:r.accountCode}),e.jsx("td",{className:"px-3 py-2 text-sm",children:r.accountName}),e.jsx("td",{className:"px-3 py-2 text-sm text-right fin-num",children:(r.debit||r.debitAmount||0)>0&&o(r.debit||r.debitAmount||0)}),e.jsx("td",{className:"px-3 py-2 text-sm text-right fin-num",children:(r.credit||r.creditAmount||0)>0&&o(r.credit||r.creditAmount||0)})]},l))}),e.jsx("tfoot",{className:"bg-gray-50",children:e.jsxs("tr",{children:[e.jsx("td",{colSpan:2,className:"px-3 py-2 text-sm font-medium text-right",children:"합계"}),e.jsx("td",{className:"px-3 py-2 text-sm font-medium text-right fin-num",children:o(t.totalDebit)}),e.jsx("td",{className:"px-3 py-2 text-sm font-medium text-right fin-num",children:o(t.totalCredit)})]})})]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[t.status==="draft"&&e.jsxs("button",{onClick:()=>_(t),className:"flex items-center gap-1 px-3 py-1.5 bg-green-600 text-white text-sm rounded-lg hover:bg-green-700 transition-colors",children:[e.jsx(ee,{className:"w-4 h-4"}),"전기"]}),t.status==="posted"&&e.jsxs("button",{onClick:()=>q(t),className:"flex items-center gap-1 px-3 py-1.5 bg-red-600 text-white text-sm rounded-lg hover:bg-red-700 transition-colors",children:[e.jsx(I,{className:"w-4 h-4"}),"역분개"]})]})]})]},t.id)})}),z&&e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:e.jsxs("div",{className:"bg-white rounded-xl shadow-xl w-full max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsx("div",{className:"sticky top-0 bg-white border-b border-gray-100 p-4",children:e.jsx("h2",{className:"text-lg font-semibold text-gray-900",children:"분개 등록"})}),e.jsxs("div",{className:"p-4 space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"일자 *"}),e.jsx("input",{type:"date",value:a.date,onChange:t=>m(s=>({...s,date:t.target.value})),className:"w-full px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"적요 *"}),e.jsx("input",{type:"text",placeholder:"거래 내용",value:a.description,onChange:t=>m(s=>({...s,description:t.target.value})),className:"w-full px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"참조번호"}),e.jsx("input",{type:"text",placeholder:"영수증번호, 청구서번호 등",value:a.reference,onChange:t=>m(s=>({...s,reference:t.target.value})),className:"w-full px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700",children:"분개 항목"}),e.jsxs("button",{type:"button",onClick:L,className:"flex items-center gap-1 text-sm text-blue-600 hover:text-blue-700",children:[e.jsx(E,{className:"w-4 h-4"}),"항목 추가"]})]}),e.jsxs("table",{className:"w-full border border-gray-200 rounded-lg overflow-hidden",children:[e.jsx("thead",{className:"bg-gray-50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 text-left text-xs font-medium text-gray-500",children:"계정"}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium text-gray-500 w-32",children:"차변"}),e.jsx("th",{className:"px-3 py-2 text-right text-xs font-medium text-gray-500 w-32",children:"대변"}),e.jsx("th",{className:"px-3 py-2 w-10"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-200",children:a.entries.map((t,s)=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-3 py-2",children:e.jsxs("select",{value:t.accountCode,onChange:r=>N(s,"accountCode",r.target.value),className:"w-full px-2 py-1.5 border border-gray-200 rounded text-sm focus:outline-none focus:ring-2 focus:ring-blue-500",children:[e.jsx("option",{value:"",children:"계정 선택"}),w.filter(r=>r.level===3&&r.isActive).map(r=>e.jsxs("option",{value:r.code,children:[r.code," - ",r.name]},r.id))]})}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("input",{type:"number",placeholder:"0",value:t.debitAmount||"",onChange:r=>N(s,"debitAmount",Number(r.target.value)),className:"w-full px-2 py-1.5 border border-gray-200 rounded text-sm text-right focus:outline-none focus:ring-2 focus:ring-blue-500",min:"0"})}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("input",{type:"number",placeholder:"0",value:t.creditAmount||"",onChange:r=>N(s,"creditAmount",Number(r.target.value)),className:"w-full px-2 py-1.5 border border-gray-200 rounded text-sm text-right focus:outline-none focus:ring-2 focus:ring-blue-500",min:"0"})}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("button",{type:"button",onClick:()=>U(s),className:"p-1 text-gray-400 hover:text-red-500 transition-colors",children:e.jsx(te,{className:"w-4 h-4"})})})]},s))}),e.jsx("tfoot",{className:"bg-gray-50",children:e.jsxs("tr",{children:[e.jsx("td",{className:"px-3 py-2 text-sm font-medium text-right",children:"합계"}),e.jsx("td",{className:"px-3 py-2 text-sm font-medium text-right fin-num",children:o(J)}),e.jsx("td",{className:"px-3 py-2 text-sm font-medium text-right fin-num",children:o(T)}),e.jsx("td",{})]})})]}),e.jsx("div",{className:`mt-2 flex items-center gap-2 text-sm ${j?"text-green-600":"text-red-600"}`,children:j?e.jsxs(e.Fragment,{children:[e.jsx(B,{className:"w-4 h-4"}),"대차 균형이 맞습니다"]}):e.jsxs(e.Fragment,{children:[e.jsx(se,{className:"w-4 h-4"}),"차액: ",o(Math.abs(J-T))]})})]})]}),e.jsxs("div",{className:"sticky bottom-0 bg-white border-t border-gray-100 p-4 flex justify-end gap-3",children:[e.jsx("button",{onClick:()=>{y(!1),S()},className:"px-4 py-2 border border-gray-200 rounded-lg text-gray-700 hover:bg-gray-50 transition-colors",children:"취소"}),e.jsx("button",{onClick:X,disabled:!j,className:"px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:"등록"})]})]})})]})}export{me as JournalListPage};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.