Skip to content

Commit

Permalink
modify: making payslip to store info of company / staff, not isolated…
Browse files Browse the repository at this point in the history
… like wl/bonus/deduction, because once the payslip is complete, all wl/bonus/deduction will not be changable, including deleting/editing
  • Loading branch information
BigSillyTiger committed Apr 26, 2024
1 parent e2995c4 commit 32e89e2
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 70 deletions.
29 changes: 6 additions & 23 deletions src/components/table/tableBtn/PSDisplayBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { PointerEventHandler, useMemo, type FC } from "react";
import {
usePayslipStore,
useStaffStore,
useStaffWLStore,
} from "@/configs/zustore";
import { usePayslipStore, useStaffWLStore } from "@/configs/zustore";
import { Tbonus, Tpayslip } from "@/configs/schema/payslipSchema";
import { useAtom } from "jotai";
import { atModalOpen, atStaff } from "@/configs/atoms";
import { auToISO } from "@/lib/time";
import { atModalOpen } from "@/configs/atoms";
import { mOpenOps } from "@/configs/utils/modal";
import { DocumentIcon } from "@heroicons/react/24/outline";

Expand All @@ -18,19 +13,12 @@ type Tprops = {

const PSDisplayBtn: FC<Tprops> = ({ payslip, name }) => {
const [, setModalOpen] = useAtom(atModalOpen);
const allStaff = useStaffStore((state) => state.allStaff);
const [, setStaff] = useAtom(atStaff); // single staff
const allStaffWL = useStaffWLStore((state) => state.allStaffWL);
const setPayslip = usePayslipStore((state) => state.setPayslip);
const allBonus = usePayslipStore((state) => state.allBonus);
const setPayslip = usePayslipStore((state) => state.setPayslip);
const setStaffWL = usePayslipStore((state) => state.setStaffWL);
const setDayRange = usePayslipStore((state) => state.setDayRange);
const setDeduction = usePayslipStore((state) => state.setDeduction);
const setAllBonus = usePayslipStore((state) => state.setAllBonus);

/* preparing the data */
// find the staff that has the specific payslip
const staff = allStaff.find((staff) => staff.uid === payslip.fk_uid)!;
const setBonus = usePayslipStore((state) => state.setBonus);

const newStaffWL = useMemo(() => {
return allStaffWL.filter((wl) => wl.fk_psid === payslip.psid);
Expand All @@ -46,6 +34,7 @@ const PSDisplayBtn: FC<Tprops> = ({ payslip, name }) => {
.filter((wl) => wl !== undefined)[0];
}, [newStaffWL]);

// filter the bonus for the current payslip with psid/fk_psid
const newBonus = useMemo(() => {
return allBonus
.map((bonus) => {
Expand All @@ -62,17 +51,11 @@ const PSDisplayBtn: FC<Tprops> = ({ payslip, name }) => {
const handleClick: PointerEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault();

//
setPayslip(payslip);
setStaff(staff);
setStaffWL(newStaffWL);
// deduction could be undefined
newDeduct && newDeduct.length && setDeduction(newDeduct);
newBonus && newBonus.length && setAllBonus(newBonus);
setDayRange({
from: new Date(auToISO(payslip.s_date)),
to: new Date(auToISO(payslip.e_date)),
});
newBonus && newBonus.length && setBonus(newBonus);
//
setModalOpen(mOpenOps.display);
// using del_2 because the del is occupied by staff del modal
Expand Down
15 changes: 12 additions & 3 deletions src/configs/schema/payslipSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,20 @@ export const payslipSchema = z.object({
fk_uid: z.string().default(""),
created_date: z.string().default(""),
status: z.literal("pending").or(z.literal("completed")).default("pending"),
hr: z.number().default(0),
hr: z.number().default(25),
paid: z.number().default(0),
s_date: z.string().default(""),
e_date: z.string().default(""),
archive: z.boolean().default(false),
company_name: z.string().default(""),
company_addr: z.string().default(""),
company_phone: z.string().default(""),
staff_name: z.string().default(""),
staff_addr: z.string().default(""),
staff_phone: z.string().default(""),
staff_email: z.string().default(""),
staff_bsb: z.string().default(""),
staff_acc: z.string().default(""),
});

const bonusSchema = z.object({
Expand All @@ -20,11 +29,11 @@ const bonusSchema = z.object({
amount: z.number().multipleOf(0.01).default(0),
});

const payslipsSchema = payslipSchema.extend({
const payslipWBDSchema = payslipSchema.extend({
bonus: bonusSchema.array().default([]),
deduction: deductionSchema.array().default([]),
});

export type Tpayslip = z.infer<typeof payslipSchema>;
export type Tpayslips = z.infer<typeof payslipsSchema>;
export type TpayslipWBD = z.infer<typeof payslipWBDSchema>;
export type Tbonus = z.infer<typeof bonusSchema>;
1 change: 1 addition & 0 deletions src/configs/utils/staff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const roleOptions = {

manager: {
...genMenuIDObject(2),
calendar: 0,
},
};

Expand Down
51 changes: 43 additions & 8 deletions src/configs/zustore/payslipStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,36 @@ import { useStore } from "zustand";
import { createStore } from "zustand/vanilla";
import { DateRange } from "react-day-picker";
import { TwlTableRow } from "../schema/workSchema";
import { Tbonus, Tpayslips } from "../schema/payslipSchema";
import { Tbonus, Tpayslip } from "../schema/payslipSchema";
import { Tdeduction } from "../schema/workSchema";
import { Tstaff } from "../schema/staffSchema";
import { Tcompany } from "../schema/settingSchema";

type Tstate = {
dayRange: DateRange;
staffWL: TwlTableRow[];
// this bonus is for current payslip
// this bonus is for current payslip, used in payslip template
bonus: Partial<Tbonus>[];
deduction: Partial<Tdeduction>[];
payslip: Partial<Tpayslips>;
payslip: Partial<Tpayslip>;
// this bonus is for all bonus from bonus table
allBonus: Tbonus[];
};

type Taction = {
resetAll: () => void;
setPayslip: (payslip: Partial<Tpayslips>) => void;
setDayRange: (range: DateRange | undefined) => void;
setStaffWL: (worklogs: TwlTableRow[]) => void;
/* payslip */
setPayslip: (payslip: Partial<Tpayslip>) => void;
setPayslipDayrange: (from: string, to: string) => void;
setPayslipStaff: (staff: Tstaff) => void;
setPayslipCompany: (company: Tcompany) => void;
setPayslipDate: (date: string) => void;
setPayslipPSID: (id: string) => void;
/* bonus */
setAllBonus: (bonus: Partial<Tbonus>[]) => void;
setBonus: (bonus: Partial<Tbonus>[]) => void;
setAllBonus: (bonus: Tbonus[]) => void;
setBonusAmount: (index: number, amount: number) => void;
setBonusNote: (index: number, note: string) => void;
appendBonus: (bonus: Partial<Tbonus>) => void;
Expand All @@ -47,18 +56,44 @@ export const payslipStore = createStore<Tstate & Taction>((set) => ({
deduction: [],
}));
},
setPayslip: (payslip: Partial<Tpayslips>) =>
set((state) => ({ ...state, payslip: payslip })),

setDayRange: (range: DateRange | undefined) =>
set((state) => ({ ...state, dayRange: range })),
setStaffWL: (worklogs: TwlTableRow[]) =>
set((state) => ({
...state,
staffWL: worklogs,
})),
/* payslip */
setPayslip: (payslip: Partial<Tpayslip>) =>
set((state) => ({ ...state, payslip: payslip })),
setPayslipDayrange: (from: string, to: string) =>
set((state) => ({ ...state, s_date: from, e_date: to })),
setPayslipStaff: (staff: Tstaff) =>
set((state) => ({
...state,
hr: staff.hr,
staff_name: `${staff.first_name} ${staff.last_name}`,
staff_addr: staff.address,
staff_phone: staff.phone,
staff_email: staff.email,
staff_bsb: staff.bsb,
staff_acc: staff.account,
})),
setPayslipCompany: (company: Tcompany) =>
set((state) => ({
...state,
company_name: company.name,
company_addr: company.address,
company_phone: company.phone,
})),
setPayslipDate: (date: string) => set((state) => ({ ...state, date })),
setPayslipPSID: (id: string) => set((state) => ({ ...state, psid: id })),
/* bonus */
setAllBonus: (bonus: Partial<Tbonus>[]) =>
setBonus: (bonus: Partial<Tbonus>[]) =>
set((state) => ({ ...state, bonus })),
setAllBonus: (allBonus: Tbonus[]) =>
set((state) => ({ ...state, allBonus })),
setBonusAmount: (index: number, amount: number) =>
set((state) => {
const newBonus = [...state.bonus];
Expand Down
10 changes: 9 additions & 1 deletion src/pageComponents/DayPicker/ORDayPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FC } from "react";
import { useEffect, type FC } from "react";
import { DayPicker } from "react-day-picker";
//import "react-day-picker/dist/style.css";
import "./datepickerstyle.css";
Expand All @@ -22,6 +22,14 @@ const ORDayPicker: FC = () => {
(state) => state.setCurrentOA
);

useEffect(() => {
setCurrentOA(
orderArrangement.find((order) => {
return order.date === dateFormat(selectedDate);
})!
);
}, [selectedDate, orderArrangement, setCurrentOA]);

const scheduledDays = orderArrangement.map((order) => new Date(order.date));

const css = `
Expand Down
12 changes: 11 additions & 1 deletion src/pageComponents/modals/mPayslip/PSSubmitBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useTranslation } from "react-i18next";
import { Form, useNavigation, useSubmit } from "react-router-dom";
import { toastWarning } from "@/lib/toaster";
import { SubmitBtn } from "@/components/form";
import { atStaff } from "@/configs/atoms";
import { atCompany, atStaff } from "@/configs/atoms";
import { useAtom } from "jotai";
import { calWorkTime, dateFormat } from "@/lib/time";
import { convertWorkHour, minusAB, plusAB, timesAB } from "@/lib/calculations";
Expand All @@ -34,6 +34,7 @@ const PSSubmitBtn: FC<Tprops> = ({ onClose }) => {
const submit = useSubmit();
const navigation = useNavigation();
const [staff] = useAtom(atStaff);
const [company] = useAtom(atCompany);
const currentRouter = useRouterStore((state) => state.currentRouter);
const bonus = usePayslipStore((state) => state.bonus);
const staffWL = usePayslipStore((state) => state.staffWL);
Expand Down Expand Up @@ -100,6 +101,15 @@ const PSSubmitBtn: FC<Tprops> = ({ onClose }) => {
s_date: dateFormat(dayRange.from),
e_date: dateFormat(dayRange.to),
paid,
company_name: company.name,
company_addr: company.address,
company_phone: company.phone,
staff_name: `${staff.first_name} ${staff.last_name}`,
staff_addr: staff.address,
staff_phone: staff.phone,
staff_email: staff.email,
staff_bsb: staff.bsb,
staff_acc: staff.account,
}),
},
{
Expand Down
3 changes: 2 additions & 1 deletion src/pageComponents/modals/mTimeTracker/mTimeTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import TimeCard from "./TimeCard";
import atResetModal from "@/configs/atoms/atResetModal";
import { TwlTableRow } from "@/configs/schema/workSchema";
import { useEffect } from "react";
import { ROLES } from "@/configs/utils/staff";

const MTimeTracker = () => {
//const submit = useSubmit();
Expand Down Expand Up @@ -78,7 +79,7 @@ const MTimeTracker = () => {
<WorkInfoCard work={worklog} className="grow-1" />
</div>
{/* time */}
{currentAdmin.role === "admin" ? (
{currentAdmin.role === ROLES.manager ? (
<SdTabs items={tabsContent()} className="col-span-1" />
) : (
<TimeCard isDisabled={isDisabled} />
Expand Down
31 changes: 20 additions & 11 deletions src/pageComponents/pdfTemplates/payslip/template1/BillTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@ import type { FC } from "react";
import { Text, View } from "@react-pdf/renderer";
import { createTw } from "react-pdf-tailwind";
import { useTranslation } from "react-i18next";
import { Tstaff } from "@/configs/schema/staffSchema";

type Tprops = {
staff: Tstaff;
staffName: string;
staffPhone: string;
staffEmail: string;
staffBSB: string;
staffACC: string;
startP: string;
endP: string;
};

const tw = createTw({});

const PayTitle: FC<Tprops> = ({ staff, startP, endP }) => {
const BillTitle: FC<Tprops> = ({
staffName,
staffPhone,
staffEmail,
staffBSB,
staffACC,
startP,
endP,
}) => {
const { t } = useTranslation();

return (
Expand All @@ -25,28 +36,26 @@ const PayTitle: FC<Tprops> = ({ staff, startP, endP }) => {
<Text style={tw("text-lg leading-7 text-teal-600")}>
{t("label.payTo")}
</Text>
<Text style={tw("text-lg leading-7 ml-2")}>
{staff.first_name + " " + staff.last_name}
</Text>
<Text style={tw("text-lg leading-7 ml-2")}>{staffName}</Text>
</View>
<View style={tw("flex flex-row gap-x-4 w-[523pt]")}>
{/* left */}
<View style={tw("flex-1 items-start")}>
<Text style={tw("text-base leading-5 text-teal-700")}>
{t("label.tel")}:{" "}
<Text style={tw("text-zinc-700")}>{staff.phone}</Text>
<Text style={tw("text-zinc-700")}>{staffPhone}</Text>
</Text>
<Text style={tw("text-base leading-5 text-teal-700")}>
{t("label.email1")}:{" "}
<Text style={tw("text-zinc-700")}>{staff.email}</Text>
<Text style={tw("text-zinc-700")}>{staffEmail}</Text>
</Text>
<Text style={tw("text-base leading-5 text-teal-700")}>
{t("label.bsb")}:{" "}
<Text style={tw("text-zinc-700")}>{staff.bsb}</Text>
<Text style={tw("text-zinc-700")}>{staffBSB}</Text>
</Text>
<Text style={tw("text-base leading-5 text-teal-700")}>
{t("label.acc")}:{" "}
<Text style={tw("text-zinc-700")}>{staff.account}</Text>
<Text style={tw("text-zinc-700")}>{staffACC}</Text>
</Text>
</View>
{/* right */}
Expand All @@ -67,4 +76,4 @@ const PayTitle: FC<Tprops> = ({ staff, startP, endP }) => {
);
};

export default PayTitle;
export default BillTitle;
20 changes: 14 additions & 6 deletions src/pageComponents/pdfTemplates/payslip/template1/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ import type { FC } from "react";
import { Text, View, Image } from "@react-pdf/renderer";
import { createTw } from "react-pdf-tailwind";
import { useTranslation } from "react-i18next";
import { Tcompany } from "@/configs/schema/settingSchema";
import { dateFormat } from "@/lib/time";

type Tprops = {
company: Tcompany;
companyName: string;
companyAddr: string;
companyPhone: string;
payslipID: string;
issueDate: string;
logo: string;
};

const tw = createTw({});

const Title: FC<Tprops> = ({ company, payslipID, issueDate, logo }) => {
const Title: FC<Tprops> = ({
companyName,
companyAddr,
companyPhone,
payslipID,
issueDate,
logo,
}) => {
const { t } = useTranslation();

return (
Expand All @@ -27,14 +35,14 @@ const Title: FC<Tprops> = ({ company, payslipID, issueDate, logo }) => {
<Image src={logo} style={tw("rounded-lg h-20 w-20")} />
{/* company */}
<View style={tw("flex justify-center")}>
<Text style={tw("font-bold text-base")}>{company.name}</Text>
<Text style={tw("font-bold text-base")}>{companyName}</Text>
<Text style={tw("text-xs text-gray-600")}>
{t("label.address") + ":"}
{company.address}
{companyAddr}
</Text>
<Text style={tw("text-xs text-gray-600")}>
{t("label.tel") + ":"}
{company.phone}
{companyPhone}
</Text>
</View>
{/* invoice */}
Expand Down
Loading

0 comments on commit 32e89e2

Please sign in to comment.