This commit is contained in:
omkieit 2024-10-07 17:52:01 +05:30
parent 4adf7fe668
commit cf4368f855
5 changed files with 657 additions and 100 deletions

View File

@ -106,6 +106,26 @@ const propertySchema = mongoose.Schema({
type: Number, type: Number,
required: true, // Set to true if this field is mandatory required: true, // Set to true if this field is mandatory
}, },
cashAdjustments: [
{
title: {
type: String,
required: true, // Set to true if this field is mandatory
},
price: {
type: Number,
required: true, // Set to true if this field is mandatory
},
},
],
totalcashAdjustments:{
type: Number,
required: true, // Set to true if this field is mandatory
},
totalcashsurplus :{
type: Number,
required: true, // Set to true if this field is mandatory
},
incidentalCost: [ incidentalCost: [
{ {
title: { title: {
@ -138,6 +158,22 @@ const propertySchema = mongoose.Schema({
type: Number, type: Number,
required: true, // Set to true if this field is mandatory required: true, // Set to true if this field is mandatory
}, },
renovationCost: [
{
title: {
type: String,
required: true, // Set to true if this field is mandatory
},
price: {
type: Number,
required: true, // Set to true if this field is mandatory
},
},
],
totalrenovationCost:{
type: Number,
required: true, // Set to true if this field is mandatory
},
}); });
const PropertyModal = mongoose.model("property", propertySchema); const PropertyModal = mongoose.model("property", propertySchema);

File diff suppressed because one or more lines are too long

85
ef-ui/dist/assets/index-KWwl6oqn.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -45,7 +45,7 @@
<script type="module" crossorigin src="/assets/index-BXhlX8aB.js"></script> <script type="module" crossorigin src="/assets/index-KWwl6oqn.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css"> <link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css">
</head> </head>

View File

@ -40,6 +40,7 @@ const Addproperty = () => {
{ title: "Property Tax", price: "" }, { title: "Property Tax", price: "" },
], ],
credits: [{ title: "Credits received on settlement", price: "" }], credits: [{ title: "Credits received on settlement", price: "" }],
cashAdjustments: [{ title: "Credits received on settlement", price: "" }],
incidentalCost: [ incidentalCost: [
{ title: "Accounting Fees", price: "" }, { title: "Accounting Fees", price: "" },
{ title: "Bank Charges", price: "" }, { title: "Bank Charges", price: "" },
@ -63,6 +64,19 @@ const Addproperty = () => {
{ title: "Security", price: "" }, { title: "Security", price: "" },
{ title: "Real Estates fees", price: "" }, { title: "Real Estates fees", price: "" },
], ],
renovationCost: [
{ title: "Demolition: Removing existing structures or finishes", price: "" },
{ title: "Framing: Making structural changes or additions", price: "" },
{ title: "Plumbing: Installing or modifying plumbing systems", price: "" },
{ title: "Electrical: Updating wiring and fixtures", price: "" },
{ title: "HVAC: Installing or upgrading heating and cooling systems", price: "" },
{ title: "Insulation: Adding or replacing insulation", price: "" },
{ title: "Drywall: Hanging and finishing drywall", price: "" },
{ title: "Interior Finishes: Painting, flooring, cabinetry, and fixtures", price: "" },
{ title: "Exterior Work: Addressing siding, roofing, or landscaping, if applicable", price: "" },
{ title: "Final Inspections: Ensuring everything meets codes", price: "" },
{ title: "Punch List: Completing any remaining task", price: "" },
],
}); });
const [submitted, setSubmitted] = useState(false); const [submitted, setSubmitted] = useState(false);
@ -250,11 +264,70 @@ const Addproperty = () => {
// Convert purchase cost to number // Convert purchase cost to number
const purchaseCost = parseFloat(formData.purchaseCost) || 0; const purchaseCost = parseFloat(formData.purchaseCost) || 0;
// Return the sum of total costs from both arrays and purchase cost
return totalCostsFromArray + totalCreditsFromArray + purchaseCost; return totalCostsFromArray + totalCreditsFromArray + purchaseCost;
}; };
const addcashAdjustments = () => {
setFormData((prevData) => ({
...prevData,
cashAdjustments: [...prevData.cashAdjustments, { title: "", price: "" }],
}));
};
const deletecashAdjustments = (index) => {
const updatedcashAdjustments = formData.cashAdjustments.filter(
(_, i) => i !== index
);
setFormData((prevData) => ({
...prevData,
cashAdjustments: updatedcashAdjustments,
}));
};
// Function to handle changes to cashAdjustments title and price
const handlecashAdjustmentsTitle = (index, field, value) => {
const updatedcashAdjustments = [...formData.cashAdjustments];
updatedcashAdjustments[index][field] = value;
setFormData((prevData) => ({
...prevData,
cashAdjustments: updatedcashAdjustments,
}));
};
const handlecashAdjustmentsCostChange = (e, index) => {
const value = e.target.value;
// Regular expression to allow only numbers and optional decimals
const isNumber = /^\d*\.?\d*$/.test(value);
// If valid number, update state, otherwise show the alert
if (isNumber || value === "") {
const updatedcashAdjustments = formData.cashAdjustments.map(
(cashAdjustments, i) =>
i === index
? { ...cashAdjustments, price: value, isInvalid: false } // Reset isInvalid if valid number
: cashAdjustments
);
setFormData({ ...formData, cashAdjustments: updatedcashAdjustments });
} else {
const updatedcashAdjustments = formData.cashAdjustments.map(
(cashAdjustments, i) =>
i === index
? { ...cashAdjustments, isInvalid: true } // Set isInvalid true for invalid input
: cashAdjustments
);
setFormData({ ...formData, cashAdjustments: updatedcashAdjustments });
}
};
// Calculate total from cash Adjustments array
const calculatecashAdjustments = () => {
return formData.cashAdjustments.reduce((total, cashAdjustments) => {
const price = parseFloat(cashAdjustments.price);
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
}, 0);
};
const addincidentalCost = () => { const addincidentalCost = () => {
setFormData((prevData) => ({ setFormData((prevData) => ({
...prevData, ...prevData,
@ -316,6 +389,7 @@ const Addproperty = () => {
}, 0); }, 0);
}; };
const addutilMaintenanceCost = () => { const addutilMaintenanceCost = () => {
setFormData((prevData) => ({ setFormData((prevData) => ({
...prevData, ...prevData,
@ -377,6 +451,100 @@ const Addproperty = () => {
}, 0); }, 0);
}; };
const addrenovationCost = () => {
setFormData((prevData) => ({
...prevData,
renovationCost: [...prevData.renovationCost, { title: "", price: "" }],
}));
};
const deleterenovationCost = (index) => {
const updatedrenovationCost = formData.renovationCost.filter(
(_, i) => i !== index
);
setFormData((prevData) => ({
...prevData,
renovationCost: updatedrenovationCost,
}));
};
// Function to handle changes to renovation Cost title and price
const handlerenovationCostTitle = (index, field, value) => {
const updatedrenovationCost = [...formData.renovationCost];
updatedrenovationCost[index][field] = value;
setFormData((prevData) => ({
...prevData,
renovationCost: updatedrenovationCost,
}));
};
const handlerenovationCostChange = (e, index) => {
const value = e.target.value;
// Regular expression to allow only numbers and optional decimals
const isNumber = /^\d*\.?\d*$/.test(value);
// If valid number, update state, otherwise show the alert
if (isNumber || value === "") {
const updatedrenovationCost = formData.renovationCost.map(
(renovationCost, i) =>
i === index
? { ...renovationCost, price: value, isInvalid: false } // Reset isInvalid if valid number
: renovationCost
);
setFormData({ ...formData, renovationCost: updatedrenovationCost });
} else {
const updatedrenovationCost = formData.renovationCost.map(
(renovationCost, i) =>
i === index
? { ...renovationCost, isInvalid: true } // Set isInvalid true for invalid input
: renovationCost
);
setFormData({ ...formData, renovationCost: updatedrenovationCost });
}
};
// Calculate total from incidentalCost array
const calculaterenovationCost = () => {
return formData.renovationCost.reduce((total, renovationCost) => {
const price = parseFloat(renovationCost.price);
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
}, 0);
};
const handleNumericInput = (e) => {
const value = e.target.value;
// Check if the input is not a valid number
if (isNaN(value)) {
setFormData({
...formData,
isInvalid: true, // Set validation flag if not a number
});
} else {
setFormData({
...formData,
totalcashsurplus: value,
isInvalid: false, // Reset validation flag if valid
});
}
};
const handleSubmit = () => { const handleSubmit = () => {
if ( if (
formData.address && formData.address &&
@ -405,13 +573,16 @@ const Addproperty = () => {
formData.sitevacant && formData.sitevacant &&
formData.extwall && formData.extwall &&
formData.roofing && formData.roofing &&
formData.totalSqft formData.totalSqft &&
formData.totalcashsurplus
) { ) {
const totalCostsAtoB = calculateTotalCosts(); const totalCostsAtoB = calculateTotalCosts();
const totalCostsAtoBaftercredits = calculateTotalCostsWithCredits(); const totalCostsAtoBaftercredits = calculateTotalCostsWithCredits();
const totalcashAdjustments = calculatecashAdjustments();
const totalincidentalCost = calculateTotalincidentalCost(); const totalincidentalCost = calculateTotalincidentalCost();
const totalcredits = calculateTotalCredits(); const totalcredits = calculateTotalCredits();
const totalutilMaintenanceCost = calculatetotalutilMaintenanceCost(); const totalutilMaintenanceCost = calculatetotalutilMaintenanceCost();
const totalrenovationCost= calculaterenovationCost();
// Add user info to formData, including the propertyTaxInfo array // Add user info to formData, including the propertyTaxInfo array
const formDataWithUserInfo = { const formDataWithUserInfo = {
@ -425,8 +596,10 @@ const Addproperty = () => {
totalCostsAtoB: totalCostsAtoB, totalCostsAtoB: totalCostsAtoB,
totalcredits: totalcredits, totalcredits: totalcredits,
totalCostsAtoBaftercredits: totalCostsAtoBaftercredits, totalCostsAtoBaftercredits: totalCostsAtoBaftercredits,
totalcashAdjustments: totalcashAdjustments,
totalincidentalCost: totalincidentalCost, totalincidentalCost: totalincidentalCost,
totalutilMaintenanceCost: totalutilMaintenanceCost, totalutilMaintenanceCost: totalutilMaintenanceCost,
totalrenovationCost:totalrenovationCost,
}; };
// Check if propertyTaxInfo is an array and has values // Check if propertyTaxInfo is an array and has values
@ -515,7 +688,14 @@ const Addproperty = () => {
> >
Property Location Property Location
</h3> </h3>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<div className="row gy-3"> <div className="row gy-3">
<div className="col-md-4"> <div className="col-md-4">
<div className="form-floating mb-3"> <div className="form-floating mb-3">
@ -1121,7 +1301,14 @@ const Addproperty = () => {
<br /> <br />
Property Tax Information Property Tax Information
</h3> </h3>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
{formData.propertyTaxInfo.map((taxInfo, index) => ( {formData.propertyTaxInfo.map((taxInfo, index) => (
<div className="row gy-4" key={index}> <div className="row gy-4" key={index}>
@ -1281,7 +1468,14 @@ const Addproperty = () => {
+ Add Image + Add Image
</button> </button>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<div className="mb-3"> <div className="mb-3">
<label htmlFor="googleMapLink" className="form-label"> <label htmlFor="googleMapLink" className="form-label">
<h3 <h3
@ -1402,7 +1596,14 @@ const Addproperty = () => {
/> />
</div> </div>
</div> </div>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<span <span
style={{ style={{
@ -1504,7 +1705,14 @@ const Addproperty = () => {
/> />
</div> </div>
</div> </div>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<span <span
style={{ style={{
@ -1513,7 +1721,7 @@ const Addproperty = () => {
fontWeight: "bold", fontWeight: "bold",
}} }}
> >
Credits Credits received on settlement:
</span> </span>
{formData.credits.map((credits, index) => ( {formData.credits.map((credits, index) => (
@ -1587,7 +1795,7 @@ const Addproperty = () => {
fontWeight: "bold", fontWeight: "bold",
}} }}
> >
Total credits Total credits received on settlement
</span> </span>
<div className="col-md-4"> <div className="col-md-4">
<input <input
@ -1606,7 +1814,14 @@ const Addproperty = () => {
</div> </div>
</div> </div>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<div className="row gy-3 align-items-center"> <div className="row gy-3 align-items-center">
<span <span
@ -1636,8 +1851,175 @@ const Addproperty = () => {
/> />
</div> </div>
</div> </div>
<hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<hr /> <span
style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}
>
Cash Adjustments:
</span>
{formData.cashAdjustments.map((cost, index) => (
<div key={index} className="row gy-3 align-items-center">
<div className="col-md-4">
<input
type="text"
className="form-control"
value={cost.title}
onChange={(e) =>
handlecashAdjustmentsTitle(
index,
"title",
e.target.value
)
}
placeholder="Title"
required
/>
</div>
<div className="col-md-4">
<input
type="text"
className={`form-control ${
cost.isInvalid ? "is-invalid" : ""
}`} // Apply 'is-invalid' class when invalid
value={cost.price}
onChange={(e) =>
handlecashAdjustmentsCostChange(e, index)
} // Use a new handler for price validation
placeholder="Price"
style={{ textAlign: "right" }}
required
/>
{cost.isInvalid && (
<div className="invalid-feedback">
Please enter a valid number.
</div>
)}
</div>
<div className="col-md-2 d-flex justify-content-start">
<button
className="btn btn-danger"
onClick={() => deletecashAdjustments(index)}
style={{ marginLeft: "5px" }}
>
x
</button>
</div>
</div>
))}
<div className="col-md-4">
<button
className="btn btn-primary back"
onClick={addcashAdjustments}
style={{ backgroundColor: "#fda417", border: "#fda417" }}
>
<span
style={{
fontSize: "20px",
fontWeight: "normal",
}}
>
+
</span>{" "}
Add Cash Adjustments
</button>
</div>
<div className="row gy-3 align-items-center">
<span
className="col-md-4"
style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}
>
Total Cash Adjustments on Settlement
</span>
<div className="col-md-4">
<input
type="text"
className="form-control"
name="totalcashAdjustments"
value={calculatecashAdjustments()}
readOnly
style={{
borderColor: "#fda417", // Custom border color for the input field
color: "#fda417", // Optionally apply text color to the input text
textAlign: "right",
}}
// placeholder="Total Incidental Cost"
required
/>
</div>
</div>
<hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<div className="row gy-3 align-items-center">
<span
className="col-md-4"
style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}
>
Total Cash Required/(Surplus) on Settlement
</span>
<div className="col-md-4">
<input
type="text"
className={`form-control ${
formData.isInvalid ? "is-invalid" : ""
}`} // Apply 'is-invalid' class if invalid
name="totalcashsurplus"
value={formData.totalcashsurplus}
onChange={handleNumericInput} // Add handler for numeric validation
style={{
borderColor: "#fda417", // Custom border color for the input field
color: "#fda417", // Optionally apply text color to the input text
textAlign: "right",
}}
placeholder="Enter only numbers"
required
/>
{formData.isInvalid && (
<div className="invalid-feedback">
Please enter a valid number.
</div>
)}
</div>
</div>
<hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<span <span
style={{ style={{
@ -1744,7 +2126,14 @@ const Addproperty = () => {
</div> </div>
</div> </div>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<span <span
style={{ style={{
@ -1853,7 +2242,139 @@ const Addproperty = () => {
</div> </div>
</div> </div>
<hr /> <hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<span
style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}
>
Renovation Costs:
</span>
{formData.renovationCost.map((cost, index) => (
<div key={index} className="row gy-3 align-items-center">
<div className="col-md-4">
<input
type="text"
className="form-control"
value={cost.title}
onChange={(e) =>
handlerenovationCostTitle(index, "title", e.target.value)
}
placeholder="Title"
required
style={{
fontSize: "10px", // Set the desired font size
}}
/>
</div>
<div className="col-md-4">
<input
type="text"
className={`form-control ${
cost.isInvalid ? "is-invalid" : ""
}`} // Apply 'is-invalid' class when invalid
value={cost.price}
onChange={(e) =>
handlerenovationCostChange(e, index)
} // Use a new handler for price validation
placeholder="Price"
style={{ textAlign: "right" }}
required
/>
{cost.isInvalid && (
<div className="invalid-feedback">
Please enter a valid number.
</div>
)}
</div>
<div className="col-md-2 d-flex justify-content-start">
<button
className="btn btn-danger"
onClick={() => deleterenovationCost(index)}
style={{ marginLeft: "5px" }}
>
x
</button>
</div>
</div>
))}
<div className="col-md-4">
<button
className="btn btn-primary back"
onClick={addrenovationCost}
style={{ backgroundColor: "#fda417", border: "#fda417" }}
>
<span
style={{
fontSize: "20px",
fontWeight: "normal",
}}
>
+
</span>{" "}
Add Renovation Cost
</button>
</div>
<div className="row gy-3 align-items-center">
<span
className="col-md-4"
style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}
>
Total Renovation Cost
</span>
<div className="col-md-4">
<input
type="text"
className="form-control"
name="totalrenovationCost"
value={calculaterenovationCost()}
readOnly
style={{
borderColor: "#fda417", // Custom border color for the input field
color: "#fda417", // Optionally apply text color to the input text
textAlign: "right",
}}
// placeholder="Total Incidental Cost"
required
/>
</div>
</div>
<hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<div className="col-md-4"> <div className="col-md-4">
<button <button