-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCostCalculationEngine.java
More file actions
295 lines (261 loc) · 10.9 KB
/
CostCalculationEngine.java
File metadata and controls
295 lines (261 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
package Professional_Cost_Calculator;
import java.text.NumberFormat;
import java.util.Locale;
/**
* ItemCost class for comprehensive cost calculation with professional features
*
* Features:
* - Professional cost calculation with tax and discount support
* - Input validation and error handling
* - Currency formatting for different locales
* - Multiple calculation methods for flexibility
* - Detailed cost breakdown and reporting
*
* @author Muhammad Yamman Hammad
* @version 2.0
*/
public class CostCalculationEngine {
// Private fields for encapsulation
private String itemName;
private double costPerItem;
private int quantity;
private double deliveryCost;
private double taxRate;
private double discountRate;
private double totalCost;
private double subtotal;
private double taxAmount;
private double discountAmount;
// Constants for validation and defaults
private static final double DEFAULT_TAX_RATE = 0.08; // 8% default tax
private static final double MIN_COST = 0.01;
private static final int MIN_QUANTITY = 1;
private static final double MAX_DISCOUNT_RATE = 0.5; // Maximum 50% discount
// Currency formatter for professional display
private static final NumberFormat CURRENCY_FORMAT = NumberFormat.getCurrencyInstance(new Locale("en", "PK"));
/**
* Default constructor with initialization
*/
public CostCalculationEngine() {
this.itemName = "";
this.costPerItem = 0.0;
this.quantity = 0;
this.deliveryCost = 0.0;
this.taxRate = DEFAULT_TAX_RATE;
this.discountRate = 0.0;
this.totalCost = 0.0;
this.subtotal = 0.0;
this.taxAmount = 0.0;
this.discountAmount = 0.0;
}
/**
* Parameterized constructor for complete item setup
*
* @param itemName Name of the item
* @param costPerItem Cost per individual item
* @param quantity Number of items
* @param deliveryCost Delivery charges
* @throws IllegalArgumentException if any parameter is invalid
*/
public CostCalculationEngine(String itemName, double costPerItem, int quantity, double deliveryCost) {
this();
setItemDetails(itemName, costPerItem, quantity, deliveryCost);
}
/**
* Sets item details with comprehensive validation
*
* @param itemName Name of the item
* @param costPerItem Cost per individual item
* @param quantity Number of items
* @param deliveryCost Delivery charges
* @throws IllegalArgumentException if any parameter is invalid
*/
public void setItemDetails(String itemName, double costPerItem, int quantity, double deliveryCost) {
validateAndSetItemName(itemName);
validateAndSetCostPerItem(costPerItem);
validateAndSetQuantity(quantity);
validateAndSetDeliveryCost(deliveryCost);
}
/**
* Basic cost calculation without delivery
*
* @param costPerItem Cost per individual item
* @param quantity Number of items
* @throws IllegalArgumentException if parameters are invalid
*/
public void calculateCost(double costPerItem, int quantity) {
validateAndSetCostPerItem(costPerItem);
validateAndSetQuantity(quantity);
this.deliveryCost = 0.0;
performCalculation();
}
/**
* Cost calculation with delivery charges
*
* @param costPerItem Cost per individual item
* @param quantity Number of items
* @param deliveryCost Delivery charges
* @throws IllegalArgumentException if parameters are invalid
*/
public void calculateCost(double costPerItem, int quantity, double deliveryCost) {
validateAndSetCostPerItem(costPerItem);
validateAndSetQuantity(quantity);
validateAndSetDeliveryCost(deliveryCost);
performCalculation();
}
/**
* Advanced cost calculation with tax and discount
*
* @param costPerItem Cost per individual item
* @param quantity Number of items
* @param deliveryCost Delivery charges
* @param taxRate Tax rate (as decimal, e.g., 0.08 for 8%)
* @param discountRate Discount rate (as decimal, e.g., 0.1 for 10%)
* @throws IllegalArgumentException if parameters are invalid
*/
public void calculateAdvancedCost(double costPerItem, int quantity, double deliveryCost,
double taxRate, double discountRate) {
validateAndSetCostPerItem(costPerItem);
validateAndSetQuantity(quantity);
validateAndSetDeliveryCost(deliveryCost);
validateAndSetTaxRate(taxRate);
validateAndSetDiscountRate(discountRate);
performCalculation();
}
/**
* Performs the actual cost calculation with all factors
*/
private void performCalculation() {
// Calculate subtotal (items + delivery)
this.subtotal = (this.costPerItem * this.quantity) + this.deliveryCost;
// Apply discount if any
this.discountAmount = this.subtotal * this.discountRate;
double afterDiscount = this.subtotal - this.discountAmount;
// Calculate tax on discounted amount
this.taxAmount = afterDiscount * this.taxRate;
// Calculate final total
this.totalCost = afterDiscount + this.taxAmount;
}
/**
* Generates a detailed cost breakdown report
*
* @return Formatted string with complete cost analysis
*/
public String generateDetailedReport() {
StringBuilder report = new StringBuilder();
report.append("\n").append("=".repeat(50)).append("\n");
report.append(" DETAILED COST BREAKDOWN\n");
report.append("=".repeat(50)).append("\n");
if (!itemName.isEmpty()) {
report.append(String.format("Item Name : %s%n", itemName));
}
report.append(String.format("Cost Per Item : %s%n", CURRENCY_FORMAT.format(costPerItem)));
report.append(String.format("Quantity : %d items%n", quantity));
report.append(String.format("Items Subtotal : %s%n", CURRENCY_FORMAT.format(costPerItem * quantity)));
if (deliveryCost > 0) {
report.append(String.format("Delivery Charges : %s%n", CURRENCY_FORMAT.format(deliveryCost)));
}
report.append(String.format("Subtotal : %s%n", CURRENCY_FORMAT.format(subtotal)));
if (discountRate > 0) {
report.append(String.format("Discount (%.1f%%) : -%s%n",
discountRate * 100, CURRENCY_FORMAT.format(discountAmount)));
}
if (taxRate > 0) {
report.append(String.format("Tax (%.1f%%) : %s%n",
taxRate * 100, CURRENCY_FORMAT.format(taxAmount)));
}
report.append("-".repeat(50)).append("\n");
report.append(String.format("TOTAL COST : %s%n", CURRENCY_FORMAT.format(totalCost)));
report.append("=".repeat(50)).append("\n");
return report.toString();
}
/**
* Generates a simple cost summary
*
* @return Formatted string with basic cost information
*/
public String generateSummary() {
return String.format("Total Cost: %s (Items: %d × %s + Delivery: %s)",
CURRENCY_FORMAT.format(totalCost),
quantity,
CURRENCY_FORMAT.format(costPerItem),
CURRENCY_FORMAT.format(deliveryCost));
}
// Validation methods
private void validateAndSetItemName(String itemName) {
if (itemName != null && !itemName.trim().isEmpty()) {
this.itemName = itemName.trim();
} else {
this.itemName = "Item";
}
}
private void validateAndSetCostPerItem(double costPerItem) {
if (costPerItem < MIN_COST) {
throw new IllegalArgumentException(
String.format("Cost per item must be at least %s", CURRENCY_FORMAT.format(MIN_COST)));
}
this.costPerItem = costPerItem;
}
private void validateAndSetQuantity(int quantity) {
if (quantity < MIN_QUANTITY) {
throw new IllegalArgumentException(
String.format("Quantity must be at least %d", MIN_QUANTITY));
}
this.quantity = quantity;
}
private void validateAndSetDeliveryCost(double deliveryCost) {
if (deliveryCost < 0) {
throw new IllegalArgumentException("Delivery cost cannot be negative");
}
this.deliveryCost = deliveryCost;
}
private void validateAndSetTaxRate(double taxRate) {
if (taxRate < 0 || taxRate > 1) {
throw new IllegalArgumentException("Tax rate must be between 0 and 1 (0% to 100%)");
}
this.taxRate = taxRate;
}
private void validateAndSetDiscountRate(double discountRate) {
if (discountRate < 0 || discountRate > MAX_DISCOUNT_RATE) {
throw new IllegalArgumentException(
String.format("Discount rate must be between 0 and %.0f%%", MAX_DISCOUNT_RATE * 100));
}
this.discountRate = discountRate;
}
// Getter methods for accessing calculated values
public double getTotalCost() { return totalCost; }
public double getSubtotal() { return subtotal; }
public double getTaxAmount() { return taxAmount; }
public double getDiscountAmount() { return discountAmount; }
public String getItemName() { return itemName; }
public double getCostPerItem() { return costPerItem; }
public int getQuantity() { return quantity; }
public double getDeliveryCost() { return deliveryCost; }
public double getTaxRate() { return taxRate; }
public double getDiscountRate() { return discountRate; }
// Setter methods for tax and discount rates
public void setTaxRate(double taxRate) {
validateAndSetTaxRate(taxRate);
}
public void setDiscountRate(double discountRate) {
validateAndSetDiscountRate(discountRate);
}
/**
* Applies a percentage discount to the current calculation
*
* @param discountPercentage Discount percentage (e.g., 10 for 10%)
*/
public void applyDiscount(double discountPercentage) {
setDiscountRate(discountPercentage / 100.0);
performCalculation();
}
/**
* Applies a tax rate to the current calculation
*
* @param taxPercentage Tax percentage (e.g., 8 for 8%)
*/
public void applyTax(double taxPercentage) {
setTaxRate(taxPercentage / 100.0);
performCalculation();
}
}