Cleanup
This commit is contained in:
parent
fc2d9ed56b
commit
983aeca2dc
32 changed files with 1570 additions and 27266 deletions
108
composables/useBudget.ts
Normal file
108
composables/useBudget.ts
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
import type { BudgetLine, OrgYearSettings } from '~/types/budget'
|
||||
|
||||
export function useBudget(orgId: string = 'default', year: number = new Date().getFullYear()) {
|
||||
const budgetStore = useBudgetStore()
|
||||
const cashStore = useCashStore()
|
||||
const { analyzeConcentration } = useConcentration()
|
||||
|
||||
// Initialize budget from wizard data if needed
|
||||
const initialized = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
if (!budgetStore.isInitialized) {
|
||||
await budgetStore.initializeFromWizardData()
|
||||
}
|
||||
initialized.value = true
|
||||
})
|
||||
|
||||
// Get starting cash from cash store
|
||||
const startingCash = computed(() => {
|
||||
const cash = cashStore.currentCash || 0
|
||||
const savings = cashStore.currentSavings || 0
|
||||
return cash + savings
|
||||
})
|
||||
|
||||
// Build revenue and expense arrays for the 12 months
|
||||
const revenuePlanned = computed(() => {
|
||||
const revenue = Array(12).fill(0)
|
||||
|
||||
if (!budgetStore.budgetWorksheet?.revenue) {
|
||||
return revenue
|
||||
}
|
||||
|
||||
budgetStore.budgetWorksheet.revenue.forEach(item => {
|
||||
// Get monthly values for the current year
|
||||
const today = new Date()
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const date = new Date(year, i, 1)
|
||||
const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`
|
||||
revenue[i] += item.monthlyValues?.[monthKey] || 0
|
||||
}
|
||||
})
|
||||
|
||||
return revenue
|
||||
})
|
||||
|
||||
const expensePlanned = computed(() => {
|
||||
const expenses = Array(12).fill(0)
|
||||
|
||||
if (!budgetStore.budgetWorksheet?.expenses) {
|
||||
return expenses
|
||||
}
|
||||
|
||||
budgetStore.budgetWorksheet.expenses.forEach(item => {
|
||||
// Get monthly values for the current year
|
||||
const today = new Date()
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const date = new Date(year, i, 1)
|
||||
const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`
|
||||
expenses[i] += item.monthlyValues?.[monthKey] || 0
|
||||
}
|
||||
})
|
||||
|
||||
return expenses
|
||||
})
|
||||
|
||||
// Calculate diversification percentage by category
|
||||
const diversification = computed(() => {
|
||||
const revTotalsByCat: Record<string, number> = {}
|
||||
|
||||
if (!budgetStore.budgetWorksheet?.revenue) {
|
||||
return {
|
||||
byCategoryPct: {},
|
||||
guidance: 'No revenue data available'
|
||||
}
|
||||
}
|
||||
|
||||
// Sum annual revenue by category
|
||||
budgetStore.budgetWorksheet.revenue.forEach(item => {
|
||||
const category = item.mainCategory || 'Other'
|
||||
const annualAmount = Object.values(item.monthlyValues || {}).reduce((sum, val) => sum + val, 0)
|
||||
revTotalsByCat[category] = (revTotalsByCat[category] || 0) + annualAmount
|
||||
})
|
||||
|
||||
const totalRev = Object.values(revTotalsByCat).reduce((a, b) => a + b, 0) || 1
|
||||
const byCategoryPct = Object.fromEntries(
|
||||
Object.entries(revTotalsByCat).map(([k, v]) => [k, (v / totalRev) * 100])
|
||||
)
|
||||
|
||||
// Use existing concentration analysis
|
||||
const revenueStreams = Object.entries(byCategoryPct).map(([category, pct]) => ({
|
||||
targetPct: pct
|
||||
}))
|
||||
|
||||
const analysis = analyzeConcentration(revenueStreams)
|
||||
|
||||
return {
|
||||
byCategoryPct,
|
||||
guidance: analysis.message
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
startingCash,
|
||||
revenuePlanned,
|
||||
expensePlanned,
|
||||
diversification
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import { allocatePayroll as allocatePayrollImpl, monthlyPayroll, type Member, type PayPolicy } from '~/types/members'
|
||||
import { useCoopBuilderStore } from '~/stores/coopBuilder'
|
||||
|
||||
export function useCoopBuilder() {
|
||||
// Use the centralized Pinia store
|
||||
|
|
@ -323,6 +324,30 @@ export function useCoopBuilder() {
|
|||
store.loadDefaultData()
|
||||
}
|
||||
|
||||
// Watch for policy and operating mode changes to refresh budget payroll
|
||||
// This needs to be after computed values are defined
|
||||
if (typeof window !== 'undefined') {
|
||||
const budgetStore = useBudgetStore()
|
||||
|
||||
// Watch for policy changes
|
||||
watch(() => [policy.value.relationship, policy.value.roleBands, operatingMode.value, store.equalHourlyWage, store.payrollOncostPct], () => {
|
||||
if (budgetStore.isInitialized) {
|
||||
nextTick(() => {
|
||||
budgetStore.refreshPayrollInBudget()
|
||||
})
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// Watch for member changes
|
||||
watch(() => store.members, () => {
|
||||
if (budgetStore.isInitialized) {
|
||||
nextTick(() => {
|
||||
budgetStore.refreshPayrollInBudget()
|
||||
})
|
||||
}
|
||||
}, { deep: true })
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
members,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue