Subversion Repositories SmartDukaan

Rev

Rev 37070 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
21543 ashik.ali 1
package com.spice.profitmandi.common.util;
2
 
34813 aman 3
import com.fasterxml.jackson.core.JsonProcessingException;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import com.spice.profitmandi.common.enumuration.DateTimePattern;
6
import org.apache.logging.log4j.LogManager;
7
import org.apache.logging.log4j.Logger;
8
 
9
import javax.mail.internet.InternetAddress;
34859 vikas 10
import java.text.Normalizer;
34723 vikas.jang 11
import java.time.*;
22215 ashik.ali 12
import java.time.format.DateTimeFormatter;
21543 ashik.ali 13
import java.time.format.DateTimeParseException;
21570 ashik.ali 14
import java.util.ArrayList;
15
import java.util.List;
34859 vikas 16
import java.util.Locale;
34813 aman 17
import java.util.regex.Matcher;
18
import java.util.regex.Pattern;
21543 ashik.ali 19
 
20
public class StringUtils {
21570 ashik.ali 21
 
22
	private static ObjectMapper objectMapper = new ObjectMapper();
23
 
23568 govind 24
	private static final Logger LOGGER = LogManager.getLogger(StringUtils.class);
23188 ashik.ali 25
	private static final String DATE_PATTERN = "dd/MM/yyyy";
23602 amit.gupta 26
	private static final String GADGET_COP_DATE_PATTERN = "MM/dd/yyyy";
23201 ashik.ali 27
	private static final String DATE_TIME_PATTERN = "dd/MM/yyyy HH:mm:ss";
24440 amit.gupta 28
	private static final String DATE_PATTERN_HYPHENATED = "dd-MM-yyyy";
34492 vikas.jang 29
	private static final String DATE_TIME_ABBR = "dd/MM/yyyy hh:mma";
34813 aman 30
	private static final DateTimeFormatter SHORT_MONTH_DATE_FORMATTER = DateTimeFormatter.ofPattern("d-MMM-yyyy");
31
	private static final DateTimeFormatter SHORT_MONTH_DATE_YEAR_FORMATTER = DateTimeFormatter.ofPattern("dd-MMM-yy");
21543 ashik.ali 32
	private StringUtils(){
33
 
34
	}
34813 aman 35
 
37070 amit 36
	private static final Pattern WHITESPACE_RUN = Pattern.compile("[\\s\\u00A0\\u1680\\u2000-\\u200B\\u202F\\u205F\\u3000\\uFEFF]+");
37
 
38
	/**
39
	 * Normalizes whitespace: replaces every run of whitespace-like characters
40
	 * (spaces, tabs, CR/LF, non-breaking space  , other Unicode spaces and
41
	 * zero-width characters) with a single regular space, then trims. Non-whitespace
42
	 * symbols (e.g. the degree sign) are preserved. Null-safe.
43
	 */
44
	public static String normalizeWhitespace(String value) {
45
		if (value == null) {
46
			return null;
47
		}
48
		return WHITESPACE_RUN.matcher(value).replaceAll(" ").trim();
49
	}
50
 
34813 aman 51
	public static final LocalDate fromShortMonthDateYear(String dateString) throws DateTimeParseException {
52
		dateString = dateString.toLowerCase();
53
		dateString = StringUtils.capitalizeFirstChar(dateString);
54
		return LocalDate.parse(dateString, SHORT_MONTH_DATE_YEAR_FORMATTER);
55
	}
56
 
57
	public static final LocalDate fromShortMonthDate(String dateString) throws DateTimeParseException {
58
		dateString = StringUtils.capitalizeFirstChar(dateString);
59
		return LocalDate.parse(dateString, SHORT_MONTH_DATE_FORMATTER);
60
	}
61
 
34769 vikas.jang 62
	public static final LocalDate toDate(String dateString)throws DateTimeParseException{
22215 ashik.ali 63
		LOGGER.info("Converting dateString [{}] with pattern[{}]", dateString, DATE_PATTERN);
23188 ashik.ali 64
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
65
		return LocalDate.parse(dateString, dateTimeFormatter);
21543 ashik.ali 66
	}
67
 
34769 vikas.jang 68
	public static final LocalDate toDate(String dateString, String pattern)throws DateTimeParseException{
69
		LOGGER.info("Converting dateString [{}] with pattern[{}]", dateString, pattern);
70
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
71
		return LocalDate.parse(dateString, dateTimeFormatter);
72
	}
73
 
34813 aman 74
	public static final String toGadgetCopDateString(LocalDate ldt) {
23602 amit.gupta 75
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(GADGET_COP_DATE_PATTERN);
76
		return dateTimeFormatter.format(ldt);
77
	}
78
 
22895 amit.gupta 79
	public static final LocalDate fromHypendatedDate(String dateString)throws DateTimeParseException{	
80
		LOGGER.info("Converting dateString [{}] with pattern[{}]", dateString, DATE_PATTERN_HYPHENATED);
23188 ashik.ali 81
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN_HYPHENATED);
82
		return LocalDate.parse(dateString, dateTimeFormatter);
22895 amit.gupta 83
	}
84
 
21543 ashik.ali 85
	public static final LocalTime toTime(String timeString) throws DateTimeParseException{
86
		return LocalTime.parse(timeString);
87
	}
34723 vikas.jang 88
 
34761 vikas.jang 89
	public static final LocalTime secondsToTime(double totalSeconds) throws DateTimeParseException{
90
		int totalSecs = (int) Math.round(totalSeconds);
91
		int hours = totalSecs / 3600;
92
		int minutes = (totalSecs % 3600) / 60;
93
		int seconds = totalSecs % 60;
34723 vikas.jang 94
		String timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds);
95
		return LocalTime.parse(timeString);
96
	}
97
 
98
	public static final LocalTime timeDifference(LocalTime startTime, LocalTime endTime) throws DateTimeParseException{
99
		Duration duration = Duration.between(startTime, endTime);
100
		if (duration.isNegative()) {
101
			duration = duration.plusHours(24); // handle case when now is past midnight
102
		}
103
 
104
		long hours = duration.toHours();
105
		long minutes = duration.toMinutes() % 60;
106
		long seconds = duration.getSeconds() % 60;
107
 
108
		return LocalTime.of((int) hours % 24, (int) minutes, (int) seconds);
109
	}
21652 ashik.ali 110
 
21792 ashik.ali 111
	public static final LocalDateTime toDateTime(long epocTime){
112
		return Instant.ofEpochMilli(epocTime).atZone(ZoneId.systemDefault()).toLocalDateTime();
113
	}
114
 
22215 ashik.ali 115
	public static final String toString(LocalDate localDate){
116
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
22858 ashik.ali 117
		String formattedDateTime = localDate.format(formatter);
22215 ashik.ali 118
		return formattedDateTime;
119
	}
24219 amit.gupta 120
 
121
	public static final String toHyphenatedString(LocalDate localDate){
122
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_PATTERN_HYPHENATED);
123
		String formattedDateTime = localDate.format(formatter);
124
		return formattedDateTime;
125
	}
22215 ashik.ali 126
 
23017 ashik.ali 127
	public static final String toString(LocalDateTime localDateTime){
128
		if(localDateTime == null){
129
			return null;
130
		}
131
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-YYYY HH:mm:ss");
132
		return localDateTime.format(formatter);
133
	}
134
 
21652 ashik.ali 135
	public static final LocalDateTime toDateTime(String dateTimeString) throws DateTimeParseException{
22290 ashik.ali 136
		if(dateTimeString == null || dateTimeString.equals("0") || dateTimeString.isEmpty()){
21655 ashik.ali 137
			return null;
138
		}
23201 ashik.ali 139
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN);
140
		return LocalDateTime.parse(dateTimeString, dateTimeFormatter);
21652 ashik.ali 141
	}
34492 vikas.jang 142
 
143
	public static final String toLocalDateTime(String dateTimeString) throws DateTimeParseException{
144
		if(dateTimeString == null || dateTimeString.equals("0") || dateTimeString.isEmpty()){
145
			return null;
146
		}
147
		LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
148
		DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(DATE_TIME_ABBR);
149
		return dateTime.format(outputFormatter);
150
	}
34813 aman 151
 
22858 ashik.ali 152
	public static final LocalDateTime toDateTime(String dateTimeString, DateTimePattern dateTimePattern) throws DateTimeParseException{
153
		if(dateTimeString == null || dateTimeString.equals("0") || dateTimeString.isEmpty()){
154
			return null;
155
		}
156
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateTimePattern.getValue());
157
		return LocalDateTime.parse(dateTimeString, formatter);
158
	}
21543 ashik.ali 159
 
160
	public static boolean isValidMobile(String mobile){
161
		try{
162
			Long.valueOf(mobile);
163
		}
164
		catch(Exception e){
165
			return false;
166
		}
167
 
168
		if (mobile.startsWith("0")){
169
			return false;
170
		}
171
		if (mobile.length()!=10){
172
			return false;
173
		}
174
		return true;
175
	}
176
 
177
	public static boolean isValidEmailAddress(String email) {
178
		boolean result = true;
179
		try {
180
			InternetAddress emailAddr = new InternetAddress(email);
181
			emailAddr.validate();
182
		} catch (Exception ex) {
183
			result = false;
184
		}
185
		return result;
186
	}
21570 ashik.ali 187
 
37668 amit 188
	/** Characters of a GSTIN, in the order the checksum weights them. */
189
	private static final String GSTIN_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
190
 
191
	/**
192
	 * 2-digit state code, 10-char PAN (5 letters, 4 digits, 1 letter), entity number,
193
	 * the literal Z, then the checksum character.
194
	 */
195
	private static final java.util.regex.Pattern GSTIN_PATTERN =
196
			java.util.regex.Pattern.compile("^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$");
197
 
198
	/** State codes issued by GSTN: 01-38, plus 97 (other territory) and 99 (centre). */
199
	private static final java.util.regex.Pattern GSTIN_STATE_CODE =
200
			java.util.regex.Pattern.compile("^(0[1-9]|[12][0-9]|3[0-8]|97|99)$");
201
 
202
	/**
203
	 * Whether a GSTIN is well formed: shape, a real state code, and the mod-36 checksum in the
204
	 * 15th character. A blank is still allowed - the field is optional for stores that have no
205
	 * registration - so callers that need one present must check for that themselves.
206
	 * <p>
207
	 * It used to accept any 15-character string, which let a pincode ({@code 110095}, rejected
208
	 * only for being 6 characters) and outright junk ({@code Hdjiekwbdbsjskz}) reach
209
	 * fofo_store.gst_number, where billing reads it. NIC then rejects the invoice and the goods
210
	 * cannot ship. The checksum is worth having on top of the shape: of 1,570 well-formed
211
	 * partner GSTINs on record exactly one fails it, so it costs nothing and catches the
212
	 * transposed or O-for-0 typo that the pattern alone cannot see.
213
	 */
23369 ashik.ali 214
	public static boolean isValidGstNumber(String gstNumber) {
37668 amit 215
		if(gstNumber == null || gstNumber.trim().isEmpty()) {
23369 ashik.ali 216
			return true;
217
		}
37668 amit 218
		String gstin = normalizeGstNumber(gstNumber);
219
		if(!GSTIN_PATTERN.matcher(gstin).matches()) {
220
			return false;
221
		}
222
		if(!GSTIN_STATE_CODE.matcher(gstin.substring(0, 2)).matches()) {
223
			return false;
224
		}
225
		return gstin.charAt(14) == gstinChecksum(gstin);
23369 ashik.ali 226
	}
37668 amit 227
 
228
	/** Trimmed and upper-cased, so the same registration is never stored two ways. */
229
	public static String normalizeGstNumber(String gstNumber) {
230
		return gstNumber == null ? null : gstNumber.trim().toUpperCase();
231
	}
232
 
233
	/**
234
	 * GSTN's mod-36 check character over the first 14 characters: each is weighted 1, 2, 1, 2 ...
235
	 * and the two digits of each product are added separately before the total is complemented.
236
	 */
237
	private static char gstinChecksum(String gstin) {
238
		int total = 0;
239
		for(int i = 0; i < 14; i++) {
240
			int product = GSTIN_ALPHABET.indexOf(gstin.charAt(i)) * (i % 2 == 0 ? 1 : 2);
241
			total += product / 36 + product % 36;
242
		}
243
		return GSTIN_ALPHABET.charAt((36 - total % 36) % 36);
244
	}
23369 ashik.ali 245
 
21570 ashik.ali 246
	public static List<String> getDuplicateElements(List<String> elements){
247
		List<String> duplicates = new ArrayList<>();
248
		for(int i = 0; i < elements.size(); i++){
249
			for(int j = i + 1; j < elements.size(); j++){
250
				if(elements.get(i).equals(elements.get(j))){
251
					duplicates.add(elements.get(i));
252
				}
253
			}
254
		}
255
		return duplicates;
256
	}
257
 
258
	public static String toString(Object object) throws Exception{
259
		try {
260
			return objectMapper.writeValueAsString(object);
261
		} catch (JsonProcessingException e) {
262
			LOGGER.error("Error occured while converting object to json", e);
263
			throw e;
264
		}
265
	}
21756 ashik.ali 266
	public static boolean isValidPinCode(String pinCode){
267
		if(pinCode == null || pinCode.isEmpty()){
268
			return false;
269
		}
270
		if(pinCode.length() != 6){
271
			return false;
272
		}
273
		if(pinCode.startsWith("00") || pinCode.startsWith("01") || pinCode.startsWith("10")){
274
			return false;
275
		}
276
		return true;
277
 
278
	}
21792 ashik.ali 279
 
22215 ashik.ali 280
	public static String generatePolicyNumber(String prefix, int sequence){
281
		String policyNumber = String.format(prefix + "%06d", sequence);
23017 ashik.ali 282
		LOGGER.info("Generated Policy Number [{}]", policyNumber);
22215 ashik.ali 283
		return policyNumber;
284
	}
22470 ashik.ali 285
 
286
	public static String generateFofoStoreSequence(String prefix, int sequence){
287
		String fofoStoreSequenceNumber = String.format(prefix + "%03d", sequence);
23017 ashik.ali 288
		LOGGER.info("Generated Fofo Store Sequence Number [{}]", fofoStoreSequenceNumber);
22470 ashik.ali 289
		return fofoStoreSequenceNumber;
290
	}
23017 ashik.ali 291
 
23502 ashik.ali 292
	public static String generateRechageRequestId(String prefix, int sequence){
293
		String oxigenRechargeRequestId = String.format(prefix + "%06d", sequence);
294
		LOGGER.info("Generated Recharge Request Id [{}]", oxigenRechargeRequestId);
23017 ashik.ali 295
		return oxigenRechargeRequestId;
296
	}
297
 
23780 ashik.ali 298
	public static String generateDeliveryNoteId(String prefix, int sequence){
299
		String deliveryNoteId = String.format(prefix + "%06d", sequence);
300
		LOGGER.info("Generated Delivery Note Id [{}]", deliveryNoteId);
301
		return deliveryNoteId;
302
	}
303
 
23017 ashik.ali 304
	public static String toOxigenRechargeRequestDate(LocalDateTime now){
305
		StringBuilder oxigenRechargeRequestDate = new StringBuilder();
306
		oxigenRechargeRequestDate.append(now.getYear());
307
		oxigenRechargeRequestDate.append(now.getMonthValue());
308
		oxigenRechargeRequestDate.append(now.getDayOfMonth());
309
		oxigenRechargeRequestDate.append(now.getHour());
310
		oxigenRechargeRequestDate.append(now.getMinute());
311
		oxigenRechargeRequestDate.append(now.getSecond());
312
		return oxigenRechargeRequestDate.toString();
313
	}
314
 
315
	public static LocalDateTime fromOxigenRechargeRequestDate(String oxigenRechargeRequestDate){
316
		int year = Integer.parseInt(oxigenRechargeRequestDate.substring(0, 3));
317
		int month = Integer.parseInt(oxigenRechargeRequestDate.substring(4, 5));
318
		int dayOfMonth = Integer.parseInt(oxigenRechargeRequestDate.substring(6, 7));
319
		int hour = Integer.parseInt(oxigenRechargeRequestDate.substring(8, 9));
320
		int minute = Integer.parseInt(oxigenRechargeRequestDate.substring(10, 11));
321
		int second = Integer.parseInt(oxigenRechargeRequestDate.substring(12, 13));
322
		return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second);
323
	}
21675 ashik.ali 324
 
34813 aman 325
	public static String capitalizeFirstChar(String input) {
326
		if (input == null || input.isEmpty()) {
327
			return input; // Return the input if it's null or empty
328
		}
329
 
330
		// Define the regular expression to match the first alphabetic character
331
		Pattern pattern = Pattern.compile("([a-zA-Z])");
332
		Matcher matcher = pattern.matcher(input);
333
 
334
		// If the first character matches, capitalize it
335
		if (matcher.find()) {
336
			return matcher.replaceFirst(matcher.group(1).toUpperCase());
337
		}
338
 
339
		return input; // If no match is found, return the original string
340
	}
341
 
34761 vikas.jang 342
	public static String formatDistance(double distanceInMeters) {
34835 vikas 343
		if (distanceInMeters <= 950) {
344
			int roundedMeters = ((int) Math.ceil(distanceInMeters / 100.0)) * 100;
345
			double distanceKm = roundedMeters / 1000.0;
346
			return String.format("%.2f", distanceKm);
34761 vikas.jang 347
		} else {
34835 vikas 348
			return String.format("%.2f", distanceInMeters / 1000.0);
34761 vikas.jang 349
		}
350
	}
351
 
34859 vikas 352
	public static String toSlug(String input) {
353
		if (input == null) return "";
354
		String normalized = Normalizer.normalize(input, Normalizer.Form.NFD).replaceAll("\\p{M}", "");
355
		String lowerCase = normalized.toLowerCase(Locale.ENGLISH);
356
		String slug = lowerCase.replaceAll("[^a-z0-9]+", "-");
357
		slug = slug.replaceAll("^-+|-+$", "");
358
		return slug;
359
	}
360
 
21543 ashik.ali 361
}