Skip to content

Commit

Permalink
fix(finance): typings
Browse files Browse the repository at this point in the history
  • Loading branch information
jesusantguerrero committed Mar 23, 2024
1 parent 9b2290c commit 84b2efb
Show file tree
Hide file tree
Showing 5 changed files with 425 additions and 72 deletions.
3 changes: 2 additions & 1 deletion resources/js/domains/budget/models/budget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface IBudgetCategory extends ICategory {
hasUnderFunded: boolean;
overAssigned: boolean;
subCategories: any[]
activity: number;
}


Expand All @@ -91,4 +92,4 @@ const targetTypeNames = {

export const getTargetName = (code: string) => {
return targetTypeNames[code] ?? code;
}
}
89 changes: 68 additions & 21 deletions resources/js/domains/budget/useBudget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,39 @@
import { cloneDeep } from "lodash";
import { computed, watch, reactive, toRefs, Ref } from "vue";
import { getCategoriesTotals, getGroupTotals } from './index';
import { ICategory } from "../transactions/models";
import { IBudgetCategory } from "./models/budget";

export const BudgetState = reactive({

interface IFilterGroups {
overSpent: any[],
overAssigned: any[],
funded: any[],
underFunded: any[],
}
interface IBudgetState {
data: IBudgetCategory[];
categories: any[];
visibleCategories: any[],
filters: {
overspent: boolean,
funded: boolean,
underFunded: boolean,
},
filterGroups: IFilterGroups,
visibleFilters: Record<string, any>;
selectedBudgetIds: {
id: number|null;
groupId: number|null;
},
selectedBudget: any;
inflow?: IBudgetCategory;
outflow: IBudgetCategory[];
budgetTotals: any;
available: any;
readyToAssign: any
}

export const BudgetState: IBudgetState = reactive({
data: [],
categories: [],
visibleCategories: [],
Expand All @@ -31,15 +61,15 @@ export const BudgetState = reactive({

selectedBudget: computed(() => {
return BudgetState.selectedBudgetIds.id
? BudgetState.categories.find((cat: ICategory) => cat.id == BudgetState.selectedBudgetIds.id)
? BudgetState.categories.find((cat: IBudgetCategory) => cat.id == BudgetState.selectedBudgetIds.id)
: null;
}),
// Balance
inflow: computed(() => {
return BudgetState.data.find((category: ICategory) => category.name == 'Inflow')
return BudgetState.data.find((category: IBudgetCategory) => category.name == 'Inflow')
}),
outflow: computed(() => {
return BudgetState.data?.filter((category: ICategory) => category.name != 'Inflow')
return BudgetState.data?.filter((category: IBudgetCategory) => category.name != 'Inflow')
}),
budgetTotals: computed(() => {
return getGroupTotals(BudgetState.outflow)
Expand Down Expand Up @@ -76,30 +106,30 @@ export const BudgetState = reactive({
});

const getBudget = (budgetRawData: any) => {
const filters = {
const filters: IFilterGroups = {
overSpent: [],
overAssigned: [],
funded: [],
underFunded: []
}
let categories = [];
let categories: IBudgetCategory[] = [];
let budgetData = cloneDeep(budgetRawData)

budgetData = budgetData?.map(item => {
budgetData = budgetData?.map((item: IBudgetCategory) => {
const totals = getCategoriesTotals(item.subCategories, {
onOverspent(category) {
onOverspent(category: IBudgetCategory) {
filters.overSpent.push(category)
category.hasOverspent = true;
},
onFunded(category) {
onFunded(category: IBudgetCategory) {
filters.funded.push(category)
category.hasFunded = true;
},
onUnderFunded(category) {
onUnderFunded(category: IBudgetCategory) {
filters.underFunded.push(category)
category.hasUnderFunded = true;
},
onOverAssigned(category) {
onOverAssigned(category: IBudgetCategory) {
filters.overAssigned.push(category)
category.overAssigned = true;
}
Expand All @@ -120,7 +150,12 @@ const getBudget = (budgetRawData: any) => {
}
}

const setBudgetState = ({ filterGroups, categories, budgetData}) => {
const setBudgetState = ({ filterGroups, categories, budgetData }:{
filterGroups: IFilterGroups,
categories: IBudgetCategory[],
budgetData: any
}
) => {
BudgetState.data = cloneDeep(budgetData);
if (filterGroups) {
BudgetState.filterGroups = filterGroups;
Expand All @@ -130,8 +165,15 @@ const setBudgetState = ({ filterGroups, categories, budgetData}) => {
}
}

enum FilterNames {
Overspent = "overspent",
Funded = "funded",
Underfunded = "underFunded"
}

const setVisibleCategories = () => {
const visibleFilter = Object.keys(BudgetState.filters).find(name => BudgetState.filters[name])
// @ts-ignore
const visibleFilter = Object.keys(BudgetState.filters).find((name: string) => BudgetState.filters[name]) as FilterNames
BudgetState.visibleCategories = getVisibleCategories(BudgetState.data, visibleFilter)
}
export const useBudget = (budgets: Ref<Record<string, any>>) => {
Expand All @@ -144,6 +186,7 @@ export const useBudget = (budgets: Ref<Record<string, any>>) => {

const setBudgetFilter = (filterName: string) => {
Object.entries(BudgetState.filters).forEach(([filter, value]) => {
// @ts-ignore:: its ok not to be ok
BudgetState.filters[filter] = filterName == filter ? !value : false ;
})
setVisibleCategories();
Expand All @@ -157,19 +200,23 @@ export const useBudget = (budgets: Ref<Record<string, any>>) => {
}
}



const filterConditions = {
overspent: (category: ICategory) => category.hasOverspent,
funded: (category: ICategory) => category.hasFunded,
underFunded: (category: ICategory) => category.hasUnderFunded,
overspent: (category: IBudgetCategory) => category.hasOverspent,
funded: (category: IBudgetCategory) => category.hasFunded,
underFunded: (category: IBudgetCategory) => category.hasUnderFunded,
}

const evaluateFilterCondition = (category: ICategory, filterName: string) => {
return !filterName ? true : filterConditions[filterName](category);
const evaluateFilterCondition = (category: IBudgetCategory, filterName?: FilterNames) => {
return filterName
? filterConditions[filterName](category)
: true ;
}

function getVisibleCategories(budgetData: Record<string, any>, filterName?: string) {
function getVisibleCategories(budgetData: Record<string, any>, filterName?: FilterNames) {
const data = cloneDeep(budgetData);
const visibleGroups = data.reduce((groups, group) => {
const visibleGroups = data.reduce((groups: any, group: IBudgetCategory) => {
const groupHasFilter = group.name != 'Inflow' && evaluateFilterCondition(group, filterName)
if (groupHasFilter) {
group.subCategories = group.subCategories?.filter(subCategory => filterName ? evaluateFilterCondition(subCategory, filterName) : true)
Expand Down
105 changes: 55 additions & 50 deletions resources/js/domains/transactions/components/TransactionModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { TRANSACTION_DIRECTIONS } from "@/domains/transactions";
import { cloneDeep } from "lodash";
import { ITransaction, ITransactionLine } from "../models";
import { useTransactionStore } from "@/store/transactions";
import { useInertiaForm, validators } from "@/utils/useInertiaForm";
import LogerButton from "@/Components/atoms/LogerButton.vue";
import { useStorage } from "@vueuse/core";
Expand Down Expand Up @@ -69,7 +70,7 @@ const state = reactive({
start_date: null,
timezone_id: "America/Santo_Domingo",
},
form: useForm({
form: useInertiaForm({
name: "",
payee_id: "",
payee_label: "",
Expand All @@ -82,7 +83,11 @@ const state = reactive({
account_id: null,
total: 0,
has_splits: false,
}),
})
});
state.form.validationSchema({
description: [validators.isRequired],
});
const splits = ref<Record<string, any>[]>([])
Expand Down Expand Up @@ -208,55 +213,54 @@ const onSubmit = (addAnother = false) => {
return;
}
state.form
.transform((form) => {
const data = {
...cloneDeep(form),
resource_type_id: "MANUAL",
total: form.total,
date: format(new Date(form.date), "yyyy-MM-dd"),
status: "verified",
direction: form.is_transfer ? TRANSACTION_DIRECTIONS.WITHDRAW : form.direction,
category_id: form.is_transfer ? null : form.category_id,
...state.schedule_settings,
};
const splitItem = splitItems[0]
data.category_id = splitItem.category_id;
data.payee_id = splitItem.payee_id;
data.counter_account_id = form.is_transfer ? splitItem.counter_account_id : null;
data.account_id = splitItem.account_id;
data.total = splitItem.amount;
data.has_splits = false;
if (splitItems?.length > 1) {
data.items = splitItems;
data.has_splits = true;
}
lastSaved.value.lastSaved = data;
return data;
})
.submit(action.method, action.url(), {
preserveScroll: true,
onBefore(evt) {
if (!evt.data.total) {
alert("The balance should be more than 0");
}
},
onSuccess: () => {
state.form.reset('description', 'category_id' , 'payee_id', 'payee_label', 'total', 'has_splits');
resetSplits(lastSaved.value.lastSaved);
nextTick(() => {
const items = splits.value;
gridSplitsRef.value?.reset(items);
try {
state.form
.transform((form) => {
const data = {
...cloneDeep(form),
resource_type_id: "MANUAL",
total: form.total,
date: format(new Date(form.date), "yyyy-MM-dd"),
status: "verified",
direction: form.is_transfer ? TRANSACTION_DIRECTIONS.WITHDRAW : form.direction,
category_id: form.is_transfer ? null : form.category_id,
...state.schedule_settings,
};
const splitItem = splitItems[0]
data.category_id = splitItem.category_id;
data.payee_id = splitItem.payee_id;
data.counter_account_id = form.is_transfer ? splitItem.counter_account_id : null;
data.account_id = splitItem.account_id;
data.total = splitItem.amount;
data.has_splits = false;
if (splitItems?.length > 1) {
data.items = splitItems;
data.has_splits = true;
}
lastSaved.value.lastSaved = data;
return data;
})
if (!lastSaved.value.addAnother) {
emit("close");
}
transactionStore.emitTransaction(lastSaved as ITransaction, action.method, props.transactionData);
lastSaved.value.addAnother = false;
},
});
.submit(action.method, action.url(), {
preserveScroll: true,
onSuccess: () => {
state.form.reset('description', 'category_id' , 'payee_id', 'payee_label', 'total', 'has_splits');
resetSplits(lastSaved.value.lastSaved);
nextTick(() => {
const items = splits.value;
gridSplitsRef.value?.reset(items);
})
if (!lastSaved.value.addAnother) {
emit("close");
}
transactionStore.emitTransaction(lastSaved as ITransaction, action.method, props.transactionData);
lastSaved.value.addAnother = false;
},
});
} catch (err) {
console.log(err)
}
};
Expand Down Expand Up @@ -287,6 +291,7 @@ const saveText = computed(() => {
<div class="mt-2">
<slot name="content">
<div>
{{ form.error }}
<div class="px-4 md:flex md:space-x-2 md:px-0">
<AtField
label="Date"
Expand Down
4 changes: 4 additions & 0 deletions resources/js/domains/transactions/models/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export interface ITransactionLine {
}

export interface ICategory {
overAssigned: boolean;
hasOverspent: any;
hasFunded: any;
hasUnderFunded: any;
month: string;
id?: number;
name: string;
Expand Down
Loading

0 comments on commit 84b2efb

Please sign in to comment.