UNPKG

@accounter/client

Version:
2 lines (1 loc) • 15.6 kB
import{u as P,gD as J,t as Z,r as i,bI as W,j as e,bC as ee,B as R,bB as se,z as ae,E as te,em as ne,dr as re,b5 as oe,Q as ce,ds as le,X as C,Y as b,Z as y,_ as N,aw as _,a0 as A,bG as k,a8 as U,b8 as M,aa as ie,ab as S,az as de,ae as F,bF as H,dZ as Y,av as G,H as $,V,gE as ue,c as q,J as z,N as me,a3 as xe,F as he,aE as pe,O as je,gF as ge}from"./index-CDv8MTrU.js";import{u as K}from"./use-url-query-Cv95DWiZ.js";import{P as fe}from"./page-layout-BnRhikMQ.js";import{k as ve,B as I,X,Y as Ce,l as be,q as ye,m as Ne,n as Ae,o as Te,p as Fe,r as Me,s as Ee}from"./download-csv-4_I4JLJJ.js";import{P as Se}from"./modal-hw2uDJ0Z.js";import{F as we}from"./funnel-2GvmLyCV.js";import{T as Le}from"./index-BSXv5S5U.js";import{s as Be}from"./sub-B39VwNW-.js";import"./sequential-CjOfRLtc.js";import"./download-csv-button-FxjssS8w.js";import"./similar-transactions-modal-BrWJ90m1.js";import"./building-2-we51QwoB.js";import"./addDays-CT4mtlSF.js";import"./subMonths-R4saX6JJ.js";var Ie=ve({chartName:"BarChart",GraphicalChild:I,defaultTooltipEventType:"axis",validateTooltipEventTypes:["axis","item"],axisComponents:[{axisType:"xAxis",AxisComp:X},{axisType:"yAxis",AxisComp:Ce}],formatAxisMap:be});const De=()=>{const[{data:s,fetching:o,error:c},t]=P({query:J});c&&(console.error(`Error fetching financial accounts: ${c}`),Z.error("Error",{description:"Unable to fetch financial accounts"}));const n=i.useMemo(()=>s?.allFinancialAccounts?.sort((h,p)=>h.name>p.name?1:-1)??[],[s]),x=i.useMemo(()=>n.map(h=>({value:h.id,label:h.name})),[n]);return{fetching:o,refresh:()=>t(),financialAccounts:n,selectableFinancialAccounts:x}};function Re(s){return!s||se(s)?null:encodeURIComponent(JSON.stringify(s))}const O="balanceReportFilters",m={MONTHLY:"Monthly",BI_MONTHLY:"Bi-monthly",QUARTERLY:"Quarterly",SEMI_ANNUALLY:"Semi-Annually",ANNUALLY:"Annually"},Ue=ie({ownerId:F().optional(),fromDate:F().regex(H,"Date must be in format yyyy-mm-dd"),toDate:F().regex(H,"Date must be in format yyyy-mm-dd"),period:de([m.MONTHLY,m.BI_MONTHLY,m.QUARTERLY,m.SEMI_ANNUALLY,m.ANNUALLY]),includedCounterparties:S(F()),excludedCounterparties:S(F()),includedTags:S(F()),excludedTags:S(F()),includedAccounts:S(F()),excludedAccounts:S(F())});function Ye(s){return{ownerId:s.ownerId??void 0,fromDate:s.fromDate,toDate:s.toDate,period:s.period??m.MONTHLY,includedCounterparties:s.includedCounterparties??[],excludedCounterparties:s.excludedCounterparties??[],includedTags:s.includedTags??[],excludedTags:s.excludedTags??[],includedAccounts:s.includedAccounts??[],excludedAccounts:s.excludedAccounts??[]}}function Oe({filter:s,setFilter:o,closeModal:c}){const t=ae({resolver:te(Ue),defaultValues:Ye(s)}),{selectableAdminBusinesses:n,fetching:x}=ne(),{selectableFinancialEntities:h,fetching:p}=re(),{selectableFinancialAccounts:j,fetching:E}=De(),{selectableTags:v,fetching:T}=oe(),D=a=>{o(a),c()},w=t.watch("includedCounterparties"),l=i.useMemo(()=>w.length>0,[w]),d=t.watch("includedTags"),r=i.useMemo(()=>d.length>0,[d]),u=t.watch("includedAccounts"),g=i.useMemo(()=>u.length>0,[u]);return e.jsx(ce,{...t,children:e.jsxs("form",{onSubmit:t.handleSubmit(D),children:[e.jsxs(le,{cols:2,children:[e.jsx(C,{control:t.control,name:"ownerId",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Admin Business"}),e.jsx(N,{children:e.jsx(_,{onChange:a.onChange,data:n,value:a.value,disabled:x,placeholder:"Scroll to see all options",formPart:!0})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"fromDate",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"From Date"}),e.jsx(N,{children:e.jsx(k,{...a,onChange:f=>{const L=f?typeof f=="string"?f:U(f,"yyyy-MM-dd"):void 0;L!==a.value&&a.onChange(L)},value:a.value?new Date(a.value):void 0,popoverProps:{withinPortal:!0}})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"toDate",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"To Date"}),e.jsx(N,{children:e.jsx(k,{...a,onChange:f=>{const L=f?typeof f=="string"?f:U(f,"yyyy-MM-dd"):void 0;L!==a.value&&a.onChange(L)},value:a.value?new Date(a.value):void 0,popoverProps:{withinPortal:!0}})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"period",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Period"}),e.jsx(N,{children:e.jsx(_,{onChange:a.onChange,data:Object.values(m).map(f=>({value:f,label:f})),value:a.value,placeholder:"Select period",formPart:!0})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"includedCounterparties",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Included Counterparties"}),e.jsx(N,{children:e.jsx(M,{asChild:!0,options:h,onValueChange:a.onChange,defaultValue:a.value??[],value:a.value??[],placeholder:"Scroll to see all options",variant:"default",disabled:p})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"excludedCounterparties",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Excluded Counterparties"}),e.jsx(N,{children:e.jsx(M,{asChild:!0,options:h,onValueChange:a.onChange,defaultValue:a.value??[],value:a.value??[],placeholder:"Scroll to see all options",variant:"default",disabled:p||l})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"includedAccounts",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Included Accounts"}),e.jsx(N,{children:e.jsx(M,{asChild:!0,options:j,onValueChange:a.onChange,defaultValue:a.value??[],value:a.value??[],placeholder:"Scroll to see all options",variant:"default",disabled:E})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"excludedAccounts",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Excluded Accounts"}),e.jsx(N,{children:e.jsx(M,{asChild:!0,options:j,onValueChange:a.onChange,defaultValue:a.value??[],value:a.value??[],placeholder:"Scroll to see all options",variant:"default",disabled:E||g})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"includedTags",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Included Tags"}),e.jsx(N,{children:e.jsx(M,{asChild:!0,options:v,onValueChange:a.onChange,defaultValue:a.value??[],value:a.value??[],placeholder:"Scroll to see all options",variant:"default",disabled:T})}),e.jsx(A,{})]})}),e.jsx(C,{control:t.control,name:"excludedTags",render:({field:a})=>e.jsxs(b,{children:[e.jsx(y,{children:"Excluded Tags"}),e.jsx(N,{children:e.jsx(M,{asChild:!0,options:v,onValueChange:a.onChange,defaultValue:a.value??[],value:a.value??[],placeholder:"Scroll to see all options",variant:"default",disabled:T||r})}),e.jsx(A,{})]})})]}),e.jsxs("div",{className:"flex justify-center mt-5 gap-3",children:[e.jsx(R,{type:"submit",disabled:x,children:"Filter"}),e.jsx(R,{type:"button",variant:"destructive",onClick:c,children:"Cancel"})]})]})})}function Pe({filter:s,setFilter:o,initiallyOpened:c=!1}){const[t,n]=i.useState(c),[x,h]=i.useState(!!s),{get:p,set:j}=K();i.useEffect(()=>{const v=Re(s),T=p(O);v!==T&&j(O,v)},[s,p,j]);const E=i.useCallback(v=>{W(v,s)||(o(v),h(!!v))},[s,o]);return e.jsxs("div",{className:"flex flex-row gap-5 items-center",children:[e.jsx(Se,{opened:t,onClose:()=>n(!1),content:e.jsx(Oe,{filter:s,setFilter:E,closeModal:()=>n(!1)}),modalSize:"xl"}),e.jsx(ee,{inline:!0,size:16,disabled:!x,children:e.jsx(R,{variant:"outline",size:"icon",className:"size-7.5",onClick:()=>n(!0),children:e.jsx(we,{className:"size-5"})})})]})}const $e=({periodInfo:s})=>{const o=Y(G.Usd);return s?e.jsx($,{className:"mb-4",children:e.jsx(V,{className:"pt-6",children:e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-muted-foreground",children:"Income"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("div",{className:"h-3 w-3 rounded-sm bg-[hsl(var(--chart-1))]"}),e.jsx("p",{className:"text-2xl font-bold",children:o.format(s.income)})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-muted-foreground",children:"Expense"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("div",{className:"h-3 w-3 rounded-sm bg-[hsl(var(--chart-2))]"}),e.jsx("p",{className:"text-2xl font-bold",children:o.format(s.expense)})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-muted-foreground",children:"Delta"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("div",{className:"h-3 w-3 rounded-sm bg-[hsl(var(--chart-3))]"}),e.jsx("p",{className:"text-2xl font-bold",children:o.format(s.delta)})]}),Object.keys(s.deltaInfo).length>0&&e.jsx("div",{className:"mt-2 space-y-1",children:Object.entries(s.deltaInfo).map(([c,t])=>{const n=c,x=Y(n);return e.jsx("p",{className:"text-xs text-muted-foreground",children:x.format(t??0)},n)})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-muted-foreground",children:"Cumulative"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("div",{className:"h-3 w-3 rounded-sm bg-[hsl(var(--chart-4))]"}),e.jsx("p",{className:"text-2xl font-bold",children:o.format(s.cumulative)})]})]})]})})}):null},Ve=({periodInfo:s,onCloseExtendedTransactions:o})=>{const c=i.useMemo(()=>s?.transactions.map(p=>p.id)||[],[s?.transactions]),[{data:t,fetching:n},x]=P({query:ue,variables:{transactionIDs:c},pause:c.length===0});i.useEffect(()=>{c.length>0&&x()},[c,x]);const h=i.useMemo(()=>t?.transactionsByIDs?c.map(p=>t?.transactionsByIDs.find(j=>j.id===p)).filter(Boolean):[],[t,c]);return e.jsx($,{className:"mt-5 w-full",children:n?e.jsx(q,{}):e.jsxs(e.Fragment,{children:[e.jsx(z,{children:e.jsxs(me,{className:"flex justify-between",children:[e.jsxs("span",{children:[s?.period," Transactions"]}),e.jsxs("div",{className:"flex flex-row gap-2 items-center",children:[e.jsx(ye,{rawTransactions:h}),e.jsx(R,{variant:"link",onClick:o,children:e.jsx(xe,{className:"h-4 w-4"})})]})]})}),e.jsxs(V,{children:[e.jsx($e,{periodInfo:s}),e.jsx(Le,{transactionsProps:h})]})]})})},B={income:{label:"Income",color:"rgba(0, 255, 50, 0.5)"},expense:{label:"Expense",color:"rgba(255, 0, 0, 0.5)"},delta:{label:"Delta",color:"rgba(0, 30, 255, 0.5)"},cumulative:{label:"Cumulative Balance",color:"rgba(100, 0, 255, 0.5)"}};function _e(s,o,c){switch(c){case m.MONTHLY:{const t=String(o).padStart(2,"0");return`${s}-${t}`}case m.BI_MONTHLY:{const t=o%2===0?o-1:o,n=String(t).padStart(2,"0");return`${s}-${n}`}case m.QUARTERLY:{const t=Math.ceil(o/3);return`${s}-Q${t}`}case m.SEMI_ANNUALLY:{const t=o>6?2:1;return`${s}-H${t}`}case m.ANNUALLY:return String(s)}}function ke(s,o){switch(o){case m.MONTHLY:{const[c,t]=s.split("-");return`${t}/${c}`}case m.BI_MONTHLY:{const[c,t]=s.split("-"),n=Number(t)+1,x=String(n).padStart(2,"0");return`${t}-${x}/${c}`}case m.QUARTERLY:{const[c,t]=s.split("-");return`${t}, ${c}`}case m.SEMI_ANNUALLY:{const[c,t]=s.split("-");return`${t}, ${c}`}case m.ANNUALLY:return s}}const Q=Y(G.Usd),ns=()=>{const{setFiltersContext:s}=i.useContext(he),{userContext:o}=i.useContext(pe),{get:c}=K(),t=i.useMemo(()=>{const l={ownerId:o?.context.adminBusinessId,toDate:U(new Date,"yyyy-MM-dd"),period:m.MONTHLY,fromDate:U(Be(new Date,{years:1}),"yyyy-MM-dd"),includedCounterparties:[],excludedCounterparties:[],includedTags:[],excludedTags:[],includedAccounts:[],excludedAccounts:[]},d=c(O);if(d)try{return JSON.parse(decodeURIComponent(d))}catch(r){console.log("Error parsing balance report filters from URL:",r)}return l},[o?.context.adminBusinessId,c]),[n,x]=i.useState(t),[h,p]=i.useState(void 0),[j,E]=i.useState(Object.keys(B)),v=i.useMemo(()=>{const{ownerId:l,fromDate:d,toDate:r}=n;return{ownerId:l,fromDate:d,toDate:r}},[n]),[{data:T,fetching:D}]=P({query:ge,variables:v,pause:!n});i.useEffect(()=>{s(e.jsxs("div",{className:"flex flex-row gap-x-5",children:[e.jsx(Pe,{filter:n,setFilter:x,initiallyOpened:!n}),e.jsx(M,{options:Object.entries(B).map(([l,d])=>({label:d.label,value:l})),onValueChange:E,defaultValue:j,placeholder:"Select Data Sets",variant:"default",maxCount:1})]})),p(void 0)},[T,D,n,s,x,j]),i.useEffect(()=>{x(l=>({...l,ownerId:o?.context.adminBusinessId}))},[o]);const w=i.useMemo(()=>{if(!T?.transactionsForBalanceReport)return[];const l=new Map;T.transactionsForBalanceReport.map(r=>{if(n.includedCounterparties?.length>0){if(!r.counterparty?.id||!r.isFee&&o?.context.financialAccountsBusinessesIds?.includes(r.counterparty.id)||!n.includedCounterparties.includes(r.counterparty.id))return}else if(r.counterparty?.id&&(!r.isFee&&o?.context.financialAccountsBusinessesIds?.includes(r.counterparty.id)||n.excludedCounterparties?.includes(r.counterparty.id)))return;if(n.includedTags?.length>0){if(!r.charge?.tags||r.charge.tags.length===0||!r.charge.tags.some(a=>n.includedTags.includes(a.id)))return}else if(n.excludedTags.length>0&&r.charge?.tags.length&&r.charge.tags.some(a=>n.excludedTags.includes(a.id)))return;if(n.includedAccounts?.length>0){if(!r.account?.id||!n.includedAccounts.includes(r.account.id))return}else if(r.account?.id&&n.excludedAccounts?.includes(r.account.id))return;const u=_e(r.year,r.month,n.period);l.has(u)||l.set(u,{period:u,income:0,expense:0,delta:0,deltaInfo:{},cumulative:0,transactions:[]});const g=l.get(u);r.amountUsd.raw>0?g.income+=r.amountUsd.raw:g.expense+=r.amountUsd.raw,g.delta+=r.amountUsd.raw,g.deltaInfo[r.amount.currency]=(g.deltaInfo[r.amount.currency]||0)+r.amount.raw,g.transactions.push(r)});let d=0;return Array.from(l.entries()).sort((r,u)=>r[0].localeCompare(u[0])).map(([r,u])=>(d+=u.delta,{period:r,income:u.income,expense:u.expense,delta:u.delta,deltaInfo:u.deltaInfo,cumulative:d,transactions:u.transactions.sort((g,a)=>Math.abs(a.amountUsd.raw)-Math.abs(g.amountUsd.raw))}))},[T,n.period,n.includedCounterparties,n.excludedCounterparties,n.includedAccounts,n.excludedAccounts,n.includedTags,n.excludedTags,o?.context.financialAccountsBusinessesIds]);return e.jsx(fe,{title:"Balance Report",description:"Accounts periodical balance",children:D?e.jsx(q,{}):e.jsxs(e.Fragment,{children:[e.jsxs($,{className:"w-full",children:[e.jsx(z,{children:e.jsx(je,{children:"Click specific period to expand it's transactions data"})}),e.jsx(V,{children:e.jsx(Ne,{config:B,className:"h-150 w-full",children:e.jsxs(Ie,{accessibilityLayer:!0,data:w,onClick:l=>p(l.activeLabel),children:[e.jsx(Ae,{vertical:!1}),e.jsx(X,{dataKey:"period",tickLine:!1,tickMargin:10,axisLine:!1,tickFormatter:l=>ke(l,n.period)}),e.jsx(Te,{content:e.jsx(Fe,{formatter:(l,d,r,u)=>{const g=`bg-[var(--color-${d})]`;return u<2?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:`${g} h-2.5 w-2.5 shrink-0 rounded-[2px]`}),B[d]?.label||d,e.jsx("div",{className:"ml-auto flex items-baseline gap-0.5 font-mono font-medium tabular-nums text-foreground",children:Q.format(Number(l))})]}):e.jsxs("div",{className:"mt-1.5 flex basis-full items-center border-t pt-1.5 text-xs font-medium text-foreground",children:[e.jsx("div",{className:`h-2.5 w-2.5 shrink-0 rounded-[2px] mr-2 ${g}`}),B[d]?.label||d,e.jsx("div",{className:"ml-auto flex items-baseline gap-0.5 font-mono font-medium tabular-nums text-foreground",children:Q.format(Number(l))})]})}})}),e.jsx(Me,{content:e.jsx(Ee,{})}),j.includes("income")&&e.jsx(I,{dataKey:"income",fill:"var(--color-income)",radius:4}),j.includes("expense")&&e.jsx(I,{dataKey:"expense",fill:"var(--color-expense)",radius:4}),j.includes("delta")&&e.jsx(I,{dataKey:"delta",fill:"var(--color-delta)",radius:4}),j.includes("cumulative")&&e.jsx(I,{dataKey:"cumulative",fill:"var(--color-cumulative)",radius:4})]})})})]}),h&&e.jsx(Ve,{periodInfo:w.find(l=>l.period===h),onCloseExtendedTransactions:()=>p(void 0)})]})})};export{ns as BalanceReport};