299 lines
11 KiB
JavaScript
299 lines
11 KiB
JavaScript
import React from "react";
|
|
import {
|
|
AppFormController,
|
|
AppFormProvider,
|
|
useAppForm,
|
|
} from "../../hooks/appHooks/useAppForm";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { AddPurchasePayment, defaultPurchasePayment } from "./PurchaseSchema";
|
|
import { usePaymentAjustmentHead } from "../../hooks/masterHook/useMaster";
|
|
import { formatFigure, localToUtc } from "../../utils/appUtils";
|
|
import Label from "../common/Label";
|
|
import DatePicker from "../common/DatePicker";
|
|
import {
|
|
useAddPurchasePayment,
|
|
usePurchase,
|
|
usePurchasePaymentHistory,
|
|
} from "../../hooks/usePurchase";
|
|
import SelectField from "../common/Forms/SelectField";
|
|
import { SpinnerLoader } from "../common/Loader";
|
|
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
|
import Avatar from "../common/Avatar";
|
|
|
|
const PurchasePayment = ({ purchaseId }) => {
|
|
const {
|
|
data: Purchase,
|
|
isLoading: isPurchaseLoading,
|
|
error: purchaseError,
|
|
} = usePurchase(purchaseId);
|
|
const methods = useAppForm({
|
|
resolver: zodResolver(AddPurchasePayment),
|
|
defaultValues: defaultPurchasePayment,
|
|
});
|
|
const {
|
|
control,
|
|
register,
|
|
handleSubmit,
|
|
reset,
|
|
formState: { errors },
|
|
} = methods;
|
|
|
|
const {
|
|
data: paymentTypes,
|
|
isLoading: isPaymentTypeLoading,
|
|
isError: isPaymentTypeError,
|
|
error: paymentError,
|
|
} = usePaymentAjustmentHead(true);
|
|
|
|
const { mutate: AddPayment, isPending } = useAddPurchasePayment(() => {
|
|
handleClose();
|
|
});
|
|
const { data, isLoading, isError, error } =
|
|
usePurchasePaymentHistory(purchaseId);
|
|
const onSubmit = (formData) => {
|
|
const payload = {
|
|
...formData,
|
|
paymentReceivedDate: localToUtc(formData.paymentReceivedDate),
|
|
invoiceId: purchaseId,
|
|
};
|
|
AddPayment(payload);
|
|
};
|
|
|
|
const handleClose = (formData) => {
|
|
reset(defaultPurchasePayment);
|
|
};
|
|
return (
|
|
<div className="contianer p-1">
|
|
<div className="text-center">
|
|
<p className="fs-5 text-semibod">Supplier / Vendor Transaction </p>
|
|
</div>
|
|
<div className="row g-3">
|
|
<div className="col-12 col-sm-6 px-2 p-sm-0">
|
|
<AppFormProvider {...methods}>
|
|
<form onSubmit={handleSubmit(onSubmit)} className="p-0 text-start">
|
|
<div className="row px-md-1 px-0">
|
|
<div className="col-12 col-md-6 mb-2">
|
|
<Label required>TransanctionId</Label>
|
|
<input
|
|
type="text"
|
|
className="form-control form-control-md"
|
|
{...register("transactionId")}
|
|
/>
|
|
{errors.transactionId && (
|
|
<small className="danger-text">
|
|
{errors.transactionId.message}
|
|
</small>
|
|
)}
|
|
</div>
|
|
|
|
<div className="col-12 col-md-6 mb-2">
|
|
<Label required>Transaction Date </Label>
|
|
<DatePicker
|
|
className="w-100"
|
|
size="md"
|
|
name="paymentReceivedDate"
|
|
control={control}
|
|
minDate={
|
|
Purchase?.createdAt
|
|
? new Date(
|
|
new Date(Purchase?.createdAt).setDate(
|
|
new Date(Purchase?.createdAt).getDate() + 1
|
|
)
|
|
)
|
|
: null
|
|
}
|
|
maxDate={new Date()}
|
|
/>
|
|
{errors.paymentReceivedDate && (
|
|
<small className="danger-text">
|
|
{errors.paymentReceivedDate.message}
|
|
</small>
|
|
)}
|
|
</div>
|
|
|
|
<div className="col-12 col-md-6 mb-2">
|
|
<AppFormController
|
|
name="paymentAdjustmentHeadId"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<SelectField
|
|
label="Payment Adjustment Head"
|
|
options={paymentTypes?.data ?? []}
|
|
placeholder="Choose a Status"
|
|
required
|
|
labelKeyKey="name"
|
|
valueKeyKey="id"
|
|
value={field.value}
|
|
onChange={field.onChange}
|
|
isLoading={isPaymentTypeLoading}
|
|
className="m-0"
|
|
/>
|
|
)}
|
|
/>
|
|
{errors.paymentAdjustmentHeadId && (
|
|
<small className="danger-text">
|
|
{errors.paymentAdjustmentHeadId.message}
|
|
</small>
|
|
)}
|
|
</div>
|
|
|
|
<div className="col-12 col-md-6 mb-2">
|
|
<Label htmlFor="amount" className="form-label" required>
|
|
Amount
|
|
</Label>
|
|
<input
|
|
type="number"
|
|
id="amount"
|
|
className="form-control form-control-md"
|
|
min="1"
|
|
step="0.01"
|
|
inputMode="decimal"
|
|
{...register("amount", { valueAsNumber: true })}
|
|
/>
|
|
{errors.amount && (
|
|
<small className="danger-text">
|
|
{errors.amount.message}
|
|
</small>
|
|
)}
|
|
</div>
|
|
<div className="col-12 mb-2">
|
|
<Label htmlFor="comment" className="form-label" required>
|
|
Comment
|
|
</Label>
|
|
<textarea
|
|
id="comment"
|
|
className="form-control form-control-sm"
|
|
{...register("comment")}
|
|
/>
|
|
{errors.comment && (
|
|
<small className="danger-text">
|
|
{errors.comment.message}
|
|
</small>
|
|
)}
|
|
</div>
|
|
|
|
<div className="d-flex justify-content-end gap-3">
|
|
{" "}
|
|
<button
|
|
type="reset"
|
|
className="btn btn-label-secondary btn-sm mt-3"
|
|
onClick={() => {
|
|
handleClose();
|
|
onClose();
|
|
}}
|
|
disabled={isPending}
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
className="btn btn-primary btn-sm mt-3"
|
|
disabled={isPending}
|
|
>
|
|
{isPending ? "Please Wait..." : "Submit"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</AppFormProvider>
|
|
</div>
|
|
|
|
<div className="col-12 col-sm-6 px-2 p-sm-0">
|
|
<div className="d-flex flex-row gap-2 text-start">
|
|
<i className="bx bx-history"></i> <p>Purchase Payment Log</p>
|
|
</div>
|
|
|
|
{isLoading ? (
|
|
<SpinnerLoader />
|
|
) : (
|
|
data?.length > 0 && (
|
|
<div
|
|
className="row text-start mx-2"
|
|
style={{ maxHeight: "70vh", overflowY: "auto" }}
|
|
>
|
|
{data
|
|
.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))
|
|
.map((payment, index) => (
|
|
<div className="col-12 mb-2" key={payment.id}>
|
|
<div className=" p-2 border-start border-warning">
|
|
<div className="row">
|
|
<div className="col-12 col-md-6 d-flex justify-content-between align-items-center ">
|
|
<div>
|
|
<small className="fw-semibold me-1">
|
|
Transaction Date:
|
|
</small>{" "}
|
|
{formatUTCToLocalTime(
|
|
payment.paymentReceivedDate
|
|
)}
|
|
</div>
|
|
<span className="fs-semibold d-block d-md-none">
|
|
{formatFigure(payment.amount, {
|
|
type: "currency",
|
|
currency: "INR",
|
|
})}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="col-12 col-md-6 mb-0 d-flex align-items-center m-0">
|
|
<small className="fw-semibold me-2">
|
|
Updated By:
|
|
</small>{" "}
|
|
<Avatar
|
|
size="xs"
|
|
firstName={payment?.createdBy?.firstName}
|
|
lastName={payment?.createdBy?.lastName}
|
|
/>{" "}
|
|
{payment?.createdBy?.firstName}{" "}
|
|
{payment.createdBy?.lastName}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="row">
|
|
<div className="col-12 col-md-6">
|
|
<p className="mb-1">
|
|
<small className="fw-semibold">
|
|
Transaction ID:
|
|
</small>{" "}
|
|
{payment.transactionId}
|
|
</p>
|
|
</div>
|
|
<div className="col-12 ">
|
|
<div className="d-flex justify-content-between">
|
|
<span>
|
|
{payment?.paymentAdjustmentHead?.name}
|
|
</span>
|
|
<span className="fs-semibold d-none d-md-block">
|
|
{formatFigure(payment.amount, {
|
|
type: "currency",
|
|
currency: "INR",
|
|
})}
|
|
</span>
|
|
</div>
|
|
<p className="text-tiny m-0 mt-1">
|
|
{payment?.comment}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
)}
|
|
{data?.length === 0 && (
|
|
<div className="d-flex justify-content-center algin-items-center text-center">
|
|
<div>
|
|
|
|
<i className='bx bx-box'></i>
|
|
<p className="text-secondary">You don't have any payment yet.</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PurchasePayment;
|