Skip to content

Commit 4a4522d

Browse files
authored
Merge pull request #41 from octodemo/import_csv
Update SalesDAO to include saveAll method for bulk sales insertion
2 parents 53c32b4 + 07464e9 commit 4a4522d

File tree

4 files changed

+132
-4
lines changed

4 files changed

+132
-4
lines changed

src/main/java/net/codejava/AppController.java

+64-3
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,18 @@
3737
import org.springframework.dao.DuplicateKeyException;
3838
import java.util.Date;
3939
import javax.servlet.http.HttpSession;
40-
// import java.util.logging.Logger;
41-
// import java.util.logging.Level;
40+
// improt MultipartFile class
41+
import org.springframework.web.multipart.MultipartFile;
42+
// import portMaooing class
43+
import org.springframework.web.bind.annotation.GetMapping;
44+
import org.springframework.web.bind.annotation.PostMapping;
45+
// bufferedReader
46+
import java.io.BufferedReader;
47+
import java.io.InputStreamReader;
48+
import java.util.ArrayList;
49+
import java.time.format.DateTimeFormatter;
50+
import java.time.LocalDateTime;
51+
import java.time.ZoneId;
4252

4353
@EnableJpaRepositories(basePackages = "net.codejava")
4454
@Controller
@@ -207,5 +217,56 @@ public void exportToCSV(HttpServletResponse response) throws IOException {
207217
writer.newLine();
208218
}
209219
writer.flush();
210-
}
220+
}
221+
222+
@PostMapping("/import")
223+
public String uploadFile(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
224+
try {
225+
// Parse the file
226+
BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
227+
228+
// Validate the header
229+
String line = reader.readLine(); // Read the first line
230+
if (line == null || !line.equals("Serial Number,Item Name,Amount,Quantity,Date")) {
231+
throw new IllegalArgumentException("Invalid header. Expected 'Serial Number,Item Name,Amount,Quantity,Date'");
232+
}
233+
234+
// Validate the rest of the file
235+
while ((line = reader.readLine()) != null) {
236+
String[] fields = line.split(",");
237+
if (fields.length != 5) {
238+
throw new IllegalArgumentException("Invalid line. Each line should contain exactly 5 fields separated by commas.");
239+
}
240+
}
241+
242+
// If the file format is valid, convert it to a list of Sale objects
243+
List<Sale> sales = new ArrayList<>();
244+
reader = new BufferedReader(new InputStreamReader(file.getInputStream())); // Reset the reader
245+
reader.readLine(); // Skip the header
246+
while ((line = reader.readLine()) != null) {
247+
String[] fields = line.split(",");
248+
Sale sale = new Sale();
249+
sale.setSerialNumber(fields[0].trim());
250+
sale.setItem(fields[1].trim());
251+
252+
// Convert LocalDate to Date
253+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
254+
LocalDate date = LocalDate.parse(fields[4].trim(), formatter);
255+
Date sqlDate = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
256+
sale.setDate(sqlDate);
257+
258+
sale.setAmount((float) Double.parseDouble(fields[2].trim()));
259+
sale.setQuantity(Integer.parseInt(fields[3].trim()));
260+
sales.add(sale);
261+
}
262+
263+
// If the file format is valid, call the upload method
264+
dao.saveAll(sales);
265+
redirectAttributes.addFlashAttribute("message", "Successfully saved the list of Sale objects to the database");
266+
System.out.println("Successfully saved the list of Sale objects to the database");
267+
} catch (Exception e) {
268+
System.out.println("Error calling dao.saveAll(sales): " + e.getMessage());
269+
}
270+
return "redirect:/";
271+
}
211272
}

src/main/java/net/codejava/SalesDAO.java

+19
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,23 @@ public List<Sale> listAll() {
124124
List<Sale> listSale = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(Sale.class));
125125
return listSale;
126126
}
127+
128+
// save all sales in a list
129+
public void saveAll(List<Sale> sales) {
130+
if (sales == null) {
131+
throw new IllegalArgumentException("List of sales cannot be null");
132+
}
133+
134+
if (jdbcTemplate == null) {
135+
throw new IllegalStateException("JdbcTemplate cannot be null");
136+
}
137+
138+
SimpleJdbcInsert insertActor = new SimpleJdbcInsert(jdbcTemplate);
139+
insertActor.withTableName("sales").usingColumns("serial_number", "item", "quantity", "amount", "date");
140+
141+
for (Sale sale : sales) {
142+
BeanPropertySqlParameterSource param = new BeanPropertySqlParameterSource(sale);
143+
insertActor.execute(param);
144+
}
145+
}
127146
}

src/main/java/net/codejava/SecurityConfig.java

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.springframework.beans.factory.annotation.Autowired;
1111
import org.springframework.context.annotation.Bean;
1212
import org.springframework.security.crypto.password.PasswordEncoder;
13+
import org.springframework.http.HttpMethod;
1314

1415

1516
@EnableWebSecurity
@@ -24,8 +25,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
2425
@Override
2526
protected void configure(HttpSecurity http) throws Exception {
2627
http
28+
.csrf().disable()
2729
.authorizeRequests()
2830
.antMatchers("/login").permitAll()
31+
.antMatchers(HttpMethod.POST, "/import").permitAll()
2932
// .anyRequest().permitAll()
3033
.anyRequest().authenticated()
3134
.and()

src/main/resources/templates/index.html

+46-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,51 @@
5151
<h1>Inventory Records</h1>
5252
<a href="/new" class="modern-button">Enter New Product</a>
5353
<a href="/export" class="modern-button">Export to CSV</a>
54+
<form id="uploadForm" style="display: none;">
55+
<input type="file" id="csvFile" name="file" accept=".csv">
56+
<button type="submit" id="submitBtn">Submit</button>
57+
</form>
58+
<label for="csvFile" class="modern-button">Import from CSV</label>
59+
<div id="errorMessage" style="color: red;"></div>
60+
<script>
61+
document.getElementById('csvFile').addEventListener('change', function() {
62+
if (this.value) {
63+
document.getElementById('uploadForm').style.display = 'block';
64+
} else {
65+
document.getElementById('uploadForm').style.display = 'none';
66+
}
67+
});
68+
69+
document.getElementById('uploadForm').addEventListener('submit', function(e) {
70+
e.preventDefault();
71+
72+
var formData = new FormData();
73+
formData.append('file', document.getElementById('csvFile').files[0]);
74+
75+
fetch('/import', {
76+
method: 'POST',
77+
body: formData
78+
}).then(response => {
79+
if (!response.ok) {
80+
throw new Error('Network response was not ok');
81+
}
82+
return response.text();
83+
}).then(data => {
84+
console.log('File uploaded successfully: ' + data);
85+
// clear the file input and hide the form
86+
document.getElementById('csvFile').value = '';
87+
document.getElementById('uploadForm').style.display = 'none';
88+
89+
// Wait for 1 second before reloading the page
90+
setTimeout(function() {
91+
location.reload();
92+
}, 1000);
93+
}).catch(error => {
94+
console.error('There has been a problem with your fetch operation: ', error);
95+
document.getElementById('errorMessage').textContent = 'Error: ' + error.message;
96+
});
97+
});
98+
</script>
5499
<br><br>
55100
<div id="searchFeature">
56101
<form action="/search" method="get">
@@ -67,7 +112,7 @@ <h1>Inventory Records</h1>
67112
</div>
68113
<br />
69114
<form th:action="@{/logout}" method="post">
70-
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
115+
<!-- <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" /> -->
71116
<input type="submit" value="Logout" />
72117
</form>
73118
<br />

0 commit comments

Comments
 (0)