118 lines
3.1 KiB
TypeScript
118 lines
3.1 KiB
TypeScript
import { defineStore } from "pinia";
|
|
|
|
export const useStreamsStore = defineStore(
|
|
"streams",
|
|
() => {
|
|
// Schema version for persistence
|
|
const schemaVersion = "1.0";
|
|
|
|
// Revenue streams with all properties
|
|
const streams = ref([]);
|
|
|
|
// Computed totals
|
|
const totalTargetPct = computed(() =>
|
|
streams.value.reduce((sum, stream) => sum + (stream.targetPct || 0), 0)
|
|
);
|
|
|
|
const totalMonthlyAmount = computed(() =>
|
|
streams.value.reduce(
|
|
(sum, stream) => sum + (stream.targetMonthlyAmount || 0),
|
|
0
|
|
)
|
|
);
|
|
|
|
// Validation computed
|
|
const targetPctDeviation = computed(() => {
|
|
const total = totalTargetPct.value;
|
|
return Math.abs(100 - total);
|
|
});
|
|
|
|
const hasValidStreams = computed(() => {
|
|
return streams.value.every(
|
|
(stream) =>
|
|
stream.name &&
|
|
stream.category &&
|
|
stream.payoutDelayDays >= 0 &&
|
|
(stream.targetPct >= 0 || stream.targetMonthlyAmount >= 0)
|
|
);
|
|
});
|
|
|
|
// Wizard-required actions
|
|
function upsertStream(stream) {
|
|
const existingIndex = streams.value.findIndex((s) => s.id === stream.id);
|
|
if (existingIndex > -1) {
|
|
streams.value[existingIndex] = {
|
|
...streams.value[existingIndex],
|
|
...stream,
|
|
};
|
|
} else {
|
|
const newStream = {
|
|
id: stream.id || Date.now().toString(),
|
|
category: stream.category,
|
|
name: stream.name,
|
|
subcategory: stream.subcategory || "",
|
|
targetPct: stream.targetPct || 0,
|
|
targetMonthlyAmount: stream.targetMonthlyAmount || 0,
|
|
certainty: stream.certainty || "Aspirational", // Committed|Probable|Aspirational
|
|
payoutDelayDays: stream.payoutDelayDays || 0,
|
|
terms: stream.terms || "",
|
|
revenueSharePct: stream.revenueSharePct || 0,
|
|
platformFeePct: stream.platformFeePct || 0,
|
|
restrictions: stream.restrictions || "General", // Restricted|General
|
|
seasonalityWeights:
|
|
stream.seasonalityWeights || new Array(12).fill(1),
|
|
effortHoursPerMonth: stream.effortHoursPerMonth || 0,
|
|
...stream,
|
|
};
|
|
streams.value.push(newStream);
|
|
}
|
|
}
|
|
|
|
// Legacy actions
|
|
function addStream(stream) {
|
|
upsertStream(stream);
|
|
}
|
|
|
|
function updateStream(id, updates) {
|
|
const stream = streams.value.find((s) => s.id === id);
|
|
if (stream) {
|
|
Object.assign(stream, updates);
|
|
}
|
|
}
|
|
|
|
function removeStream(id) {
|
|
const index = streams.value.findIndex((s) => s.id === id);
|
|
if (index > -1) {
|
|
streams.value.splice(index, 1);
|
|
}
|
|
}
|
|
|
|
|
|
// Reset function
|
|
function resetStreams() {
|
|
streams.value = [];
|
|
}
|
|
|
|
return {
|
|
streams,
|
|
totalTargetPct,
|
|
totalMonthlyAmount,
|
|
targetPctDeviation,
|
|
hasValidStreams,
|
|
schemaVersion,
|
|
// Wizard actions
|
|
upsertStream,
|
|
resetStreams,
|
|
// Legacy actions
|
|
addStream,
|
|
updateStream,
|
|
removeStream,
|
|
};
|
|
},
|
|
{
|
|
persist: {
|
|
key: "urgent-tools-streams",
|
|
paths: ["streams"],
|
|
},
|
|
}
|
|
);
|