done
This commit is contained in:
parent
c996a2801d
commit
709ab255fa
|
@ -134,7 +134,6 @@ const propertySchema = mongoose.Schema({
|
|||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
},
|
||||
|
||||
totalcashrequiredonsettlement:{
|
||||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
|
@ -155,7 +154,7 @@ const propertySchema = mongoose.Schema({
|
|||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
},
|
||||
utilMaintenance: [
|
||||
carryCosts: [
|
||||
{
|
||||
title: {
|
||||
type: String,
|
||||
|
@ -167,7 +166,7 @@ const propertySchema = mongoose.Schema({
|
|||
},
|
||||
},
|
||||
],
|
||||
totalutilMaintenanceCost: {
|
||||
totalcarryCosts: {
|
||||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
},
|
||||
|
@ -187,11 +186,15 @@ const propertySchema = mongoose.Schema({
|
|||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
},
|
||||
costsAfterPropertyAcquisition:{
|
||||
totalRenovationsandHoldingCost:{
|
||||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
},
|
||||
sellpricebtoc:{
|
||||
totalCoststoBuyAtoB:{
|
||||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
},
|
||||
sellingPriceBtoC:{
|
||||
type: Number,
|
||||
required: true, // Set to true if this field is mandatory
|
||||
},
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -45,7 +45,7 @@
|
|||
|
||||
|
||||
|
||||
<script type="module" crossorigin src="/assets/index-COiggoDj.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BG8wErZt.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css">
|
||||
</head>
|
||||
|
||||
|
|
|
@ -31,73 +31,55 @@ const Addproperty = () => {
|
|||
images: [{ title: "", file: "" }], // Array to hold image objects
|
||||
googleMapLink: "", // Field for Google Maps link
|
||||
renovationRisk: null,
|
||||
purchaseCost: "",
|
||||
purchaseCost: "0",
|
||||
costPaidAtoB: [
|
||||
{ title: "Closing Fees - Settlement Fee", price: "" },
|
||||
{ title: "Closing Fees - Owner's Title Insurance", price: "" },
|
||||
{ title: "Courier Fees", price: "" },
|
||||
{ title: "Wire Fee", price: "" },
|
||||
{ title: "E recording Fee", price: "" },
|
||||
{ title: "Recording Fee", price: "" },
|
||||
{ title: "Property Tax", price: "" },
|
||||
{ title: "Closing Fees - Settlement Fee", price: "0" },
|
||||
{ title: "Closing Fees - Owner's Title Insurance", price: "0" },
|
||||
{ title: "Courier Fees", price: "0" },
|
||||
{ title: "Wire Fee", price: "0" },
|
||||
{ title: "E recording Fee", price: "0" },
|
||||
{ title: "Recording Fee", price: "0" },
|
||||
{ title: "Property Tax", price: "0" },
|
||||
],
|
||||
credits: [{ title: "Credits", price: "" }],
|
||||
cashAdjustments: [{ title: "Cash Adjustments", price: "" }],
|
||||
credits: [{ title: "Credits", price: "0" }],
|
||||
cashAdjustments: [{ title: "Cash Adjustments", price: "0" }],
|
||||
incidentalCost: [
|
||||
{ title: "Accounting Fees", price: "" },
|
||||
{ title: "Bank Charges", price: "" },
|
||||
{ title: "Legal Fees", price: "" },
|
||||
{ title: "Property Taxes", price: "" },
|
||||
{ title: "Travel Expenses", price: "" },
|
||||
{ title: "Accounting Fees", price: "0" },
|
||||
{ title: "Bank Charges", price: "0" },
|
||||
{ title: "Legal Fees", price: "0" },
|
||||
{ title: "Property Taxes", price: "0" },
|
||||
{ title: "Travel Expenses", price: "0" },
|
||||
],
|
||||
utilMaintenance: [
|
||||
{ title: "Electricity", price: "" },
|
||||
{ title: "Water and Sewer", price: "" },
|
||||
{ title: "Natural Gas", price: "" },
|
||||
{ title: "Trash and Recycling", price: "" },
|
||||
{ title: "Internet and Cable", price: "" },
|
||||
{ title: "Heating Oil/Propane", price: "" },
|
||||
{ title: "HOA fees", price: "" },
|
||||
{ title: "Dump fees", price: "" },
|
||||
{ title: "Insurance", price: "" },
|
||||
{ title: "Interest on Loans", price: "" },
|
||||
{ title: "Loan Payment", price: "" },
|
||||
{ title: "Property Taxes", price: "" },
|
||||
{ title: "Security", price: "" },
|
||||
{ title: "Real Estates fees", price: "" },
|
||||
carryCosts: [
|
||||
{ title: "Electricity", price: "0" },
|
||||
{ title: "Water and Sewer", price: "0" },
|
||||
{ title: "Natural Gas", price: "0" },
|
||||
{ title: "Trash and Recycling", price: "0" },
|
||||
{ title: "Internet and Cable", price: "0" },
|
||||
{ title: "Heating Oil/Propane", price: "0" },
|
||||
{ title: "HOA fees", price: "0" },
|
||||
{ title: "Dump fees", price: "0" },
|
||||
{ title: "Insurance", price: "0" },
|
||||
{ title: "Interest on Loans", price: "0" },
|
||||
{ title: "Loan Payment", price: "0" },
|
||||
{ title: "Property Taxes", price: "0" },
|
||||
{ title: "Security", price: "0" },
|
||||
{ title: "Real Estates fees", price: "0" },
|
||||
],
|
||||
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: "" },
|
||||
{ title: "Demolition: Removing existing structures or finishes", price: "0"},
|
||||
{ title: "Framing: Making structural changes or additions", price: "0"},
|
||||
{ title: "Plumbing: Installing or modifying plumbing systems", price: "0"},
|
||||
{ title: "Electrical: Updating wiring and fixtures", price: "0" },
|
||||
{ title: "HVAC: Installing or upgrading heating and cooling systems", price: "0"},
|
||||
{ title: "Insulation: Adding or replacing insulation", price: "0" },
|
||||
{ title: "Drywall: Hanging and finishing drywall", price: "0" },
|
||||
{ title: "Interior Finishes: Painting, flooring, cabinetry, and fixtures", price: "0"},
|
||||
{ title:"Exterior Work: Addressing siding, roofing, or landscaping, if applicable", price: "0"},
|
||||
{ title: "Final Inspections: Ensuring everything meets codes", price: "0"},
|
||||
{ title: "Punch List: Completing any remaining task", price: "0" },
|
||||
],
|
||||
sellingPriceBtoC:"0"
|
||||
});
|
||||
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
|
@ -357,7 +339,7 @@ const Addproperty = () => {
|
|||
// Sum up all the values from the three functions
|
||||
return totalcashAdjustments + totalcredits + totalPurchaseCosts;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const addincidentalCost = () => {
|
||||
setFormData((prevData) => ({
|
||||
|
@ -420,34 +402,34 @@ const Addproperty = () => {
|
|||
}, 0);
|
||||
};
|
||||
|
||||
const addutilMaintenanceCost = () => {
|
||||
const addcarryCosts = () => {
|
||||
setFormData((prevData) => ({
|
||||
...prevData,
|
||||
utilMaintenance: [...prevData.utilMaintenance, { title: "", price: "" }],
|
||||
carryCosts: [...prevData.carryCosts, { title: "", price: "" }],
|
||||
}));
|
||||
};
|
||||
|
||||
const deleteutilMaintenanceCost = (index) => {
|
||||
const updatedutilMaintenance = formData.utilMaintenance.filter(
|
||||
const deletecarryCosts = (index) => {
|
||||
const updatedcarryCosts = formData.carryCosts.filter(
|
||||
(_, i) => i !== index
|
||||
);
|
||||
setFormData((prevData) => ({
|
||||
...prevData,
|
||||
utilMaintenance: updatedutilMaintenance,
|
||||
carryCosts: updatedcarryCosts,
|
||||
}));
|
||||
};
|
||||
|
||||
// Function to handle changes to incidentalCost title and price
|
||||
const handleutilMaintenanceTitle = (index, field, value) => {
|
||||
const updatedutilMaintenance = [...formData.utilMaintenance];
|
||||
updatedutilMaintenance[index][field] = value;
|
||||
const handlecarryCostsTitle = (index, field, value) => {
|
||||
const updatedcarryCosts= [...formData.carryCosts];
|
||||
updatedcarryCosts[index][field] = value;
|
||||
setFormData((prevData) => ({
|
||||
...prevData,
|
||||
utilMaintenance: updatedutilMaintenance,
|
||||
carryCosts: updatedcarryCosts,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleutilMaintenanceCostChange = (e, index) => {
|
||||
const handlecarryCostsChange = (e, index) => {
|
||||
const value = e.target.value;
|
||||
|
||||
// Regular expression to allow only numbers and optional decimals
|
||||
|
@ -455,28 +437,28 @@ const Addproperty = () => {
|
|||
|
||||
// If valid number, update state, otherwise show the alert
|
||||
if (isNumber || value === "") {
|
||||
const updatedutilMaintenance = formData.utilMaintenance.map(
|
||||
(utilMaintenance, i) =>
|
||||
const updatedcarryCosts = formData.carryCosts.map(
|
||||
(carryCosts, i) =>
|
||||
i === index
|
||||
? { ...utilMaintenance, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||||
: utilMaintenance
|
||||
? { ...carryCosts, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||||
: carryCosts
|
||||
);
|
||||
setFormData({ ...formData, utilMaintenance: updatedutilMaintenance });
|
||||
setFormData({ ...formData, carryCosts: updatedcarryCosts });
|
||||
} else {
|
||||
const updatedutilMaintenance = formData.utilMaintenance.map(
|
||||
(utilMaintenance, i) =>
|
||||
const updatedcarryCosts = formData.carryCosts.map(
|
||||
(carryCosts, i) =>
|
||||
i === index
|
||||
? { ...utilMaintenance, isInvalid: true } // Set isInvalid true for invalid input
|
||||
: utilMaintenance
|
||||
? { ...carryCosts, isInvalid: true } // Set isInvalid true for invalid input
|
||||
: carryCosts
|
||||
);
|
||||
setFormData({ ...formData, utilMaintenance: updatedutilMaintenance });
|
||||
setFormData({ ...formData, carryCosts: updatedcarryCosts});
|
||||
}
|
||||
};
|
||||
|
||||
// Calculate total from incidentalCost array
|
||||
const calculatetotalutilMaintenanceCost = () => {
|
||||
return formData.utilMaintenance.reduce((total, utilMaintenance) => {
|
||||
const price = parseFloat(utilMaintenance.price);
|
||||
const calculatetotalcarryCosts = () => {
|
||||
return formData.carryCosts.reduce((total, carryCosts) => {
|
||||
const price = parseFloat(carryCosts.price);
|
||||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||||
}, 0);
|
||||
};
|
||||
|
@ -542,13 +524,22 @@ const Addproperty = () => {
|
|||
}, 0);
|
||||
};
|
||||
|
||||
const calculatecostsAfterPropertyAcquisition = () => {
|
||||
const calculatetotalRenovationsandHoldingCost = () => {
|
||||
const totalIncidentalCost = calculateTotalincidentalCost();
|
||||
const totalUtilMaintenanceCost = calculatetotalutilMaintenanceCost();
|
||||
const totalcarryCosts = calculatetotalcarryCosts();
|
||||
const totalRenovationCost = calculaterenovationCost();
|
||||
|
||||
// Sum up all the values from the three functions
|
||||
return totalIncidentalCost + totalUtilMaintenanceCost + totalRenovationCost;
|
||||
return totalIncidentalCost + totalcarryCosts + totalRenovationCost;
|
||||
};
|
||||
|
||||
const calculatetotalCoststoBuyAtoB =() => {
|
||||
const totalRenovationsandHoldingCost = calculatetotalRenovationsandHoldingCost();
|
||||
const totalCashRequiredonSettlement = calculateTotalCashRequiredonSettlement();
|
||||
|
||||
// Sum up all the values from the three functions
|
||||
return totalRenovationsandHoldingCost + totalCashRequiredonSettlement;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -583,8 +574,6 @@ const Addproperty = () => {
|
|||
formData.roofing &&
|
||||
formData.totalSqft &&
|
||||
formData.renovationRisk &&
|
||||
|
||||
formData.sellpricebtoc &&
|
||||
formData.closeDateAtoB &&
|
||||
formData.closeDateBtoC
|
||||
) {
|
||||
|
@ -594,10 +583,10 @@ const Addproperty = () => {
|
|||
const totalincidentalCost = calculateTotalincidentalCost();
|
||||
const totalcredits = calculateTotalCredits();
|
||||
const totalcashrequiredonsettlement = calculateTotalCashRequiredonSettlement();
|
||||
const totalutilMaintenanceCost = calculatetotalutilMaintenanceCost();
|
||||
const totalcarryCosts = calculatetotalcarryCosts();
|
||||
const totalrenovationCost = calculaterenovationCost();
|
||||
const costsAfterPropertyAcquisition =
|
||||
calculatecostsAfterPropertyAcquisition();
|
||||
const totalRenovationsandHoldingCost = calculatetotalRenovationsandHoldingCost();
|
||||
const totalCoststoBuyAtoB = calculatetotalCoststoBuyAtoB();
|
||||
|
||||
// Add user info to formData, including the propertyTaxInfo array
|
||||
const formDataWithUserInfo = {
|
||||
|
@ -614,9 +603,10 @@ const Addproperty = () => {
|
|||
totalcashAdjustments: totalcashAdjustments,
|
||||
totalcashrequiredonsettlement:totalcashrequiredonsettlement,
|
||||
totalincidentalCost: totalincidentalCost,
|
||||
totalutilMaintenanceCost: totalutilMaintenanceCost,
|
||||
totalcarryCosts: totalcarryCosts,
|
||||
totalrenovationCost: totalrenovationCost,
|
||||
costsAfterPropertyAcquisition: costsAfterPropertyAcquisition,
|
||||
totalRenovationsandHoldingCost: totalRenovationsandHoldingCost,
|
||||
totalCoststoBuyAtoB: totalCoststoBuyAtoB,
|
||||
};
|
||||
|
||||
// Check if propertyTaxInfo is an array and has values
|
||||
|
@ -2173,8 +2163,6 @@ Renovation Risk
|
|||
className="form-control"
|
||||
name="totalcashrequiredonsettlement"
|
||||
value={calculateTotalCashRequiredonSettlement()}
|
||||
|
||||
|
||||
readOnly
|
||||
style={{
|
||||
borderColor: "#fda417", // Custom border color for the input field
|
||||
|
@ -2322,7 +2310,7 @@ Renovation Risk
|
|||
Carry Costs:
|
||||
</span>
|
||||
|
||||
{formData.utilMaintenance.map((cost, index) => (
|
||||
{formData.carryCosts.map((cost, index) => (
|
||||
<div key={index} className="row gy-3 align-items-center">
|
||||
<div className="col-md-4">
|
||||
<input
|
||||
|
@ -2330,7 +2318,7 @@ Renovation Risk
|
|||
className="form-control"
|
||||
value={cost.title}
|
||||
onChange={(e) =>
|
||||
handleutilMaintenanceTitle(
|
||||
handlecarryCostsTitle(
|
||||
index,
|
||||
"title",
|
||||
e.target.value
|
||||
|
@ -2348,7 +2336,7 @@ Renovation Risk
|
|||
}`} // Apply 'is-invalid' class when invalid
|
||||
value={cost.price}
|
||||
onChange={(e) =>
|
||||
handleutilMaintenanceCostChange(e, index)
|
||||
handlecarryCostsChange(e, index)
|
||||
} // Use a new handler for price validation
|
||||
placeholder="Price"
|
||||
style={{ textAlign: "right" }}
|
||||
|
@ -2363,7 +2351,7 @@ Renovation Risk
|
|||
<div className="col-md-2 d-flex justify-content-start">
|
||||
<button
|
||||
className="btn btn-danger"
|
||||
onClick={() => deleteutilMaintenanceCost(index)}
|
||||
onClick={() => deletecarryCosts(index)}
|
||||
style={{ marginLeft: "5px" }}
|
||||
>
|
||||
x
|
||||
|
@ -2375,7 +2363,7 @@ Renovation Risk
|
|||
<div className="col-md-4">
|
||||
<button
|
||||
className="btn btn-primary back"
|
||||
onClick={addutilMaintenanceCost}
|
||||
onClick={addcarryCosts}
|
||||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||||
>
|
||||
<span
|
||||
|
@ -2405,8 +2393,8 @@ Renovation Risk
|
|||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
name="totalutilMaintenanceCost"
|
||||
value={calculatetotalutilMaintenanceCost()}
|
||||
name="totalcarryCosts"
|
||||
value={calculatetotalcarryCosts()}
|
||||
readOnly
|
||||
style={{
|
||||
borderColor: "#fda417", // Custom border color for the input field
|
||||
|
@ -2435,7 +2423,7 @@ Renovation Risk
|
|||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Renovation and Holding Costs
|
||||
Reno and Holding Costs
|
||||
</span>
|
||||
|
||||
{formData.renovationCost.map((cost, index) => (
|
||||
|
@ -2517,7 +2505,7 @@ Renovation Risk
|
|||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Total Renovation and Holding cost
|
||||
Total Renovation Cost
|
||||
</span>
|
||||
<div className="col-md-4">
|
||||
<input
|
||||
|
@ -2555,14 +2543,14 @@ Renovation Risk
|
|||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Total Costs After Property Acquisition
|
||||
Total Renovations & Holding Cost
|
||||
</span>
|
||||
<div className="col-md-4">
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
name="costsAfterPropertyAcquisition"
|
||||
value={calculatecostsAfterPropertyAcquisition()}
|
||||
name="totalRenovationsandHoldingCost"
|
||||
value={calculatetotalRenovationsandHoldingCost()}
|
||||
readOnly
|
||||
style={{
|
||||
borderColor: "#fda417", // Custom border color for the input field
|
||||
|
@ -2585,6 +2573,50 @@ Renovation Risk
|
|||
/>
|
||||
|
||||
<div className="row gy-3 align-items-center">
|
||||
<span
|
||||
className="col-md-4"
|
||||
style={{
|
||||
color: "#fda417",
|
||||
fontSize: "14px",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Total Costs to Buy A to B
|
||||
</span>
|
||||
<div className="col-md-4">
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
name="totalCoststoBuyAtoB"
|
||||
value={calculatetotalCoststoBuyAtoB()}
|
||||
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
|
||||
/>
|
||||
{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
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
<div className="row gy-3 align-items-center">
|
||||
<span
|
||||
className="col-md-4"
|
||||
style={{
|
||||
|
@ -2599,35 +2631,34 @@ Renovation Risk
|
|||
<input
|
||||
type="text"
|
||||
className={`form-control ${
|
||||
formData.isInvalid ? "is-invalid" : ""
|
||||
formData.isPurchaseCostInvalid ? "is-invalid" : ""
|
||||
}`}
|
||||
name="sellpricebtoc"
|
||||
value={formData.sellpricebtoc}
|
||||
value={formData.sellingPriceBtoC}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
const isValid = /^\d*\.?\d*$/.test(value); // Allow only numbers and decimal points
|
||||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||||
setFormData({
|
||||
...formData,
|
||||
sellpricebtoc: value,
|
||||
isInvalid: !isValid, // Set isInvalid to true if the value is not a valid number
|
||||
sellingPriceBtoC: value,
|
||||
isPurchaseCostInvalid: !isValid, // Set isPurchaseCostInvalid to true if the value is not a valid number
|
||||
});
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
const charCode = e.charCode;
|
||||
// Allow only numbers and decimal point
|
||||
// Allow only numbers and decimal points
|
||||
if ((charCode < 48 || charCode > 57) && charCode !== 46) {
|
||||
e.preventDefault(); // Prevent non-numeric input
|
||||
setFormData({
|
||||
...formData,
|
||||
isInvalid: true, // Set isInvalid to true to show the alert
|
||||
isPurchaseCostInvalid: true, // Set isPurchaseCostInvalid to true to show the alert
|
||||
});
|
||||
}
|
||||
}}
|
||||
placeholder="Selling Price B to C"
|
||||
placeholder="Enter Purchase Cost"
|
||||
style={{ textAlign: "right" }}
|
||||
required
|
||||
/>
|
||||
{formData.isInvalid && (
|
||||
{formData.isPurchaseCostInvalid && (
|
||||
<div className="invalid-feedback">
|
||||
Please enter a valid number.
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue