Subversion Repositories SmartDukaan

Rev

Rev 36120 | Rev 36138 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 36120 Rev 36137
Line 40... Line 40...
40
    private static float[] stateWidths = new float[]{.6f, 2.1f, 0.7f, .3f, 0.6f, .7f, .5f, .6f, .5f, .6f, .8f};
40
    private static float[] stateWidths = new float[]{.6f, 2.1f, 0.7f, .3f, 0.6f, .7f, .5f, .6f, .5f, .6f, .8f};
41
 
41
 
42
    private static float[] igstWidthsCrNote = new float[]{2.6f, 0.7f, .4f, 0.7f, .7f, .6f, 0.6f, 0.9f};
42
    private static float[] igstWidthsCrNote = new float[]{2.6f, 0.7f, .4f, 0.7f, .7f, .6f, 0.6f, 0.9f};
43
    private static float[] stateWidthsCrNote = new float[]{2.1f, 0.7f, .3f, 0.6f, .7f, .5f, .6f, .5f, .6f, .8f};
43
    private static float[] stateWidthsCrNote = new float[]{2.1f, 0.7f, .3f, 0.6f, .7f, .5f, .6f, .5f, .6f, .8f};
44
 
44
 
45
    private static final Locale indianLocale = Locale.getDefault();
45
    private static final Locale indianLocale = new Locale("en", "IN");
-
 
46
    private static final java.text.NumberFormat indianCurrencyFormat = java.text.NumberFormat.getCurrencyInstance(new Locale("en", "IN"));
46
 
47
 
47
    private static final Logger LOGGER = LogManager.getLogger(PdfUtils.class);
48
    private static final Logger LOGGER = LogManager.getLogger(PdfUtils.class);
48
 
49
 
49
    private static final URL iconUrl = PdfUtils.class.getClassLoader().getResource("sdlogo.png");
50
    private static final URL iconUrl = PdfUtils.class.getClassLoader().getResource("sdlogo.png");
50
    private static Image iconImg = null;
51
    private static Image iconImg = null;
Line 724... Line 725...
724
                    msAddDataCell(itemTable, String.valueOf(orderItem.getQuantity()),     Element.ALIGN_CENTER, false, false);
725
                    msAddDataCell(itemTable, String.valueOf(orderItem.getQuantity()),     Element.ALIGN_CENTER, false, false);
725
 
726
 
726
                    if (isMargin) {
727
                    if (isMargin) {
727
                        float grossSaleTotal = orderItem.getNetAmount() - taxAmount;
728
                        float grossSaleTotal = orderItem.getNetAmount() - taxAmount;
728
                        float grossSalePerUnit = grossSaleTotal / orderItem.getQuantity();
729
                        float grossSalePerUnit = grossSaleTotal / orderItem.getQuantity();
729
                        msAddDataCell(itemTable, String.format("%.2f", grossSalePerUnit),        Element.ALIGN_RIGHT, false, false);
730
                        msAddDataCell(itemTable, formatIndianCurrency(grossSalePerUnit),          Element.ALIGN_RIGHT, false, false);
730
                        totalGrossSale += grossSaleTotal;
731
                        totalGrossSale += grossSaleTotal;
731
                    } else {
732
                    } else {
732
                        msAddDataCell(itemTable, String.format("%.2f", orderItem.getRate()),      Element.ALIGN_RIGHT, false, false);
733
                        msAddDataCell(itemTable, formatIndianCurrency(orderItem.getRate()),       Element.ALIGN_RIGHT, false, false);
733
                    }
734
                    }
734
                    totalNetAmount += orderItem.getNetAmount();
735
                    totalNetAmount += orderItem.getNetAmount();
735
                    msAddDataCell(itemTable, String.format("%.2f", orderItem.getAmount()),        Element.ALIGN_RIGHT, false, false);
736
                    msAddDataCell(itemTable, formatIndianCurrency(orderItem.getAmount()),         Element.ALIGN_RIGHT, false, false);
736
                    String rateText;
737
                    String rateText;
737
                    if (stateGst) {
738
                    if (stateGst) {
738
                        rateText = String.format("CGST %.1f%%\n+ SGST %.1f%%", orderItem.getCgstRate(), orderItem.getSgstRate());
739
                        rateText = String.format("CGST %.1f%%\n+ SGST %.1f%%", orderItem.getCgstRate(), orderItem.getSgstRate());
739
                    } else {
740
                    } else {
740
                        rateText = String.format("IGST %.1f%%", orderItem.getIgstRate());
741
                        rateText = String.format("IGST %.1f%%", orderItem.getIgstRate());
741
                    }
742
                    }
742
                    msAddDataCell(itemTable, rateText,                                            Element.ALIGN_CENTER, false, false);
743
                    msAddDataCell(itemTable, rateText,                                            Element.ALIGN_CENTER, false, false);
743
                    msAddDataCell(itemTable, String.format("%.2f", taxAmount), Element.ALIGN_RIGHT, false, false);
744
                    msAddDataCell(itemTable, formatIndianCurrency(taxAmount),                     Element.ALIGN_RIGHT, false, false);
744
                    msAddDataCell(itemTable, String.format("%.0f", orderItem.getNetAmount()), Element.ALIGN_RIGHT, false, false);
745
                    msAddDataCell(itemTable, formatIndianCurrency(orderItem.getNetAmount()),      Element.ALIGN_RIGHT, false, false);
745
 
746
 
746
                    totalTaxable += orderItem.getAmount();
747
                    totalTaxable += orderItem.getAmount();
747
                    totalTaxAmount += taxAmount;
748
                    totalTaxAmount += taxAmount;
748
                    totalCgst += orderItem.getCgstAmount();
749
                    totalCgst += orderItem.getCgstAmount();
749
                    totalSgst += orderItem.getSgstAmount();
750
                    totalSgst += orderItem.getSgstAmount();
Line 760... Line 761...
760
                totalSpan.setBorderColor(MS_BORDER);
761
                totalSpan.setBorderColor(MS_BORDER);
761
                totalSpan.setBackgroundColor(MS_TOTAL_BG);
762
                totalSpan.setBackgroundColor(MS_TOTAL_BG);
762
                totalSpan.setPadding(4f);
763
                totalSpan.setPadding(4f);
763
                itemTable.addCell(totalSpan);
764
                itemTable.addCell(totalSpan);
764
 
765
 
765
                msAddDataCell(itemTable, isMargin ? String.format("%.2f", totalGrossSale) : "", Element.ALIGN_RIGHT, true, true);
766
                msAddDataCell(itemTable, isMargin ? formatIndianCurrency(totalGrossSale) : "", Element.ALIGN_RIGHT, true, true);
766
                msAddDataCell(itemTable, String.format("%.2f", totalTaxable),     Element.ALIGN_RIGHT, true, true);
767
                msAddDataCell(itemTable, formatIndianCurrency(totalTaxable),      Element.ALIGN_RIGHT, true, true);
767
                msAddDataCell(itemTable, "\u2014",                                Element.ALIGN_CENTER, false, true);
768
                msAddDataCell(itemTable, "\u2014",                                Element.ALIGN_CENTER, false, true);
768
                msAddDataCell(itemTable, String.format("%.2f", totalTaxAmount), Element.ALIGN_RIGHT, true, true);
769
                msAddDataCell(itemTable, formatIndianCurrency(totalTaxAmount),    Element.ALIGN_RIGHT, true, true);
769
                msAddDataCell(itemTable, String.format("%.0f", totalNetAmount), Element.ALIGN_RIGHT, true, true);
770
                msAddDataCell(itemTable, formatIndianCurrency(totalNetAmount),    Element.ALIGN_RIGHT, true, true);
770
 
771
 
771
                document.add(itemTable);
772
                document.add(itemTable);
772
 
773
 
773
                // ── Bottom: Info (left) + Summary (right) + Amount in words ──
774
                // ── Bottom: Info (left) + Summary (right) + Amount in words ──
774
                float totalInvoiceValue = isMargin ? (totalGrossSale + totalTaxAmount) : totalNetAmount;
775
                float totalInvoiceValue = isMargin ? (totalGrossSale + totalTaxAmount) : totalNetAmount;
Line 806... Line 807...
806
                PdfPTable sumTable = new PdfPTable(2);
807
                PdfPTable sumTable = new PdfPTable(2);
807
                sumTable.setWidthPercentage(100);
808
                sumTable.setWidthPercentage(100);
808
                sumTable.setWidths(new float[]{1.4f, 1f});
809
                sumTable.setWidths(new float[]{1.4f, 1f});
809
 
810
 
810
                if (isMargin) {
811
                if (isMargin) {
811
                    msAddSummaryRow(sumTable, "Total Selling Price", String.format("Rs. %.2f", totalGrossSale), false);
812
                    msAddSummaryRow(sumTable, "Total Selling Price", "Rs. " + formatIndianCurrency(totalGrossSale), false);
812
                    msAddSummaryRow(sumTable, "GST on Margin", String.format("Rs. %.2f", totalTaxAmount), false);
813
                    msAddSummaryRow(sumTable, "GST on Margin", "Rs. " + formatIndianCurrency(totalTaxAmount), false);
813
                } else {
814
                } else {
814
                    msAddSummaryRow(sumTable, "Total Taxable Value", String.format("Rs. %.2f", totalTaxable), false);
815
                    msAddSummaryRow(sumTable, "Total Taxable Value", "Rs. " + formatIndianCurrency(totalTaxable), false);
815
                    msAddSummaryRow(sumTable, "Total GST", String.format("Rs. %.2f", totalTaxAmount), false);
816
                    msAddSummaryRow(sumTable, "Total GST", "Rs. " + formatIndianCurrency(totalTaxAmount), false);
816
                }
817
                }
817
                msAddSummaryRow(sumTable, "Total Invoice Value", String.format("Rs. %.2f", totalInvoiceValue), true);
818
                msAddSummaryRow(sumTable, "Total Invoice Value", "Rs. " + formatIndianCurrency(totalInvoiceValue), true);
818
                summaryCell.addElement(sumTable);
819
                summaryCell.addElement(sumTable);
819
                bottomTable.addCell(summaryCell);
820
                bottomTable.addCell(summaryCell);
820
 
821
 
821
                // Row 2: empty (left) + Amount in words (right) — no gap
822
                // Row 2: empty (left) + Amount in words (right) — no gap
822
                PdfPCell emptyLeft = new PdfPCell(new Phrase("", MS_NORMAL));
823
                PdfPCell emptyLeft = new PdfPCell(new Phrase("", MS_NORMAL));
Line 1176... Line 1177...
1176
            e.printStackTrace();
1177
            e.printStackTrace();
1177
        }
1178
        }
1178
    }
1179
    }
1179
 
1180
 
1180
    private static String toAmountInWords(float amount) {
1181
    private static String toAmountInWords(float amount) {
-
 
1182
        int rupees = (int) amount;
-
 
1183
        int paise = Math.round((amount - rupees) * 100);
-
 
1184
        StringBuilder sb = new StringBuilder("Rs. ");
-
 
1185
        sb.append(StringUtils.capitalize(indianNumberToWords(rupees)));
-
 
1186
        if (paise > 0) {
-
 
1187
            sb.append(" and ");
1181
        RuleBasedNumberFormat amountInWordsFormat = new RuleBasedNumberFormat(indianLocale, RuleBasedNumberFormat.SPELLOUT);
1188
            RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(indianLocale, RuleBasedNumberFormat.SPELLOUT);
-
 
1189
            sb.append(StringUtils.capitalize(fmt.format(paise)));
-
 
1190
            sb.append(" Paise");
-
 
1191
        } else {
-
 
1192
            sb.append(" Only");
-
 
1193
        }
-
 
1194
        return sb.toString();
-
 
1195
    }
-
 
1196
 
-
 
1197
    /**
-
 
1198
     * Convert number to Indian English words (lakh, crore system).
-
 
1199
     */
-
 
1200
    private static String indianNumberToWords(int number) {
-
 
1201
        if (number == 0) return "zero";
-
 
1202
        String[] ones = {"", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
-
 
1203
                "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
-
 
1204
                "eighteen", "nineteen"};
-
 
1205
        String[] tens = {"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
-
 
1206
 
-
 
1207
        if (number < 0) return "minus " + indianNumberToWords(-number);
-
 
1208
 
1182
        StringBuilder amountInWords = new StringBuilder("Rs. ");
1209
        StringBuilder words = new StringBuilder();
-
 
1210
        if (number / 10000000 > 0) {
1183
        amountInWords.append(StringUtils.capitalize(amountInWordsFormat.format((int) amount)));
1211
            words.append(indianNumberToWords(number / 10000000)).append(" crore ");
-
 
1212
            number %= 10000000;
-
 
1213
        }
1184
        amountInWords.append(" and ");
1214
        if (number / 100000 > 0) {
-
 
1215
            words.append(indianNumberToWords(number / 100000)).append(" lakh ");
-
 
1216
            number %= 100000;
-
 
1217
        }
-
 
1218
        if (number / 1000 > 0) {
1185
        amountInWords.append(StringUtils.capitalize(amountInWordsFormat.format((int) (amount * 100) % 100)));
1219
            words.append(indianNumberToWords(number / 1000)).append(" thousand ");
-
 
1220
            number %= 1000;
-
 
1221
        }
-
 
1222
        if (number / 100 > 0) {
-
 
1223
            words.append(ones[number / 100]).append(" hundred ");
-
 
1224
            number %= 100;
-
 
1225
        }
-
 
1226
        if (number > 0) {
-
 
1227
            if (words.length() > 0) words.append("and ");
-
 
1228
            if (number < 20) {
1186
        amountInWords.append(" paise");
1229
                words.append(ones[number]);
-
 
1230
            } else {
-
 
1231
                words.append(tens[number / 10]);
-
 
1232
                if (number % 10 > 0) words.append("-").append(ones[number % 10]);
-
 
1233
            }
-
 
1234
        }
1187
        return amountInWords.toString();
1235
        return words.toString().trim();
-
 
1236
    }
-
 
1237
 
-
 
1238
    /**
-
 
1239
     * Format amount in Indian comma style: 1,25,129.00
-
 
1240
     */
-
 
1241
    static String formatIndianCurrency(double amount) {
-
 
1242
        String formatted = indianCurrencyFormat.format(amount);
-
 
1243
        // Remove currency symbol, keep just the number with commas
-
 
1244
        return formatted.replaceAll("[^0-9,.]", "").trim();
1188
    }
1245
    }
1189
 
1246
 
1190
    public static void generateAndWriteCustomerCreditNotes(List<CreditNotePdfModel> creditNotes, OutputStream outputStream) {
1247
    public static void generateAndWriteCustomerCreditNotes(List<CreditNotePdfModel> creditNotes, OutputStream outputStream) {
1191
        Document document = new Document();
1248
        Document document = new Document();
1192
        document.setMargins(0, 0, 25, 0);
1249
        document.setMargins(0, 0, 25, 0);