| 37066 |
amit |
1 |
package com.spice.profitmandi.common.document;
|
|
|
2 |
|
|
|
3 |
import com.spice.profitmandi.common.model.CustomCustomer;
|
| 37379 |
amit |
4 |
import com.spice.profitmandi.common.model.CustomInsurancePolicy;
|
| 37066 |
amit |
5 |
import com.spice.profitmandi.common.model.CustomOrderItem;
|
|
|
6 |
import com.spice.profitmandi.common.model.CustomPaymentOption;
|
|
|
7 |
import com.spice.profitmandi.common.model.CustomRetailer;
|
|
|
8 |
import com.spice.profitmandi.common.model.EWayBillPdfModel;
|
|
|
9 |
import com.spice.profitmandi.common.model.InvoicePdfModel;
|
|
|
10 |
import com.spice.profitmandi.common.model.IrnModel;
|
|
|
11 |
|
| 37379 |
amit |
12 |
import java.util.ArrayList;
|
| 37066 |
amit |
13 |
import java.util.List;
|
|
|
14 |
|
|
|
15 |
/**
|
|
|
16 |
* Normalized view of a printable document, consumed by the rendering {@code Section}s.
|
|
|
17 |
*
|
|
|
18 |
* <p>All four document types (tax invoice V1/V2, delivery challan, debit note, credit note)
|
|
|
19 |
* ultimately carry an {@link InvoicePdfModel}; debit/credit notes simply wrap one and override the
|
|
|
20 |
* document number/date. This holder resolves those differences once — document number, date,
|
|
|
21 |
* {@link DocumentType} and display title — and delegates everything else to the wrapped model, so
|
|
|
22 |
* the sections never branch on which source type produced the document.
|
|
|
23 |
*/
|
|
|
24 |
public class DocumentData {
|
|
|
25 |
|
|
|
26 |
public enum DocumentType {
|
|
|
27 |
TAX_INVOICE("Invoice No:", "INVOICE DETAILS", "Total Invoice Value", "invoice"),
|
|
|
28 |
DELIVERY_CHALLAN("Challan No:", "CHALLAN DETAILS", "Total Challan Value", "delivery challan"),
|
|
|
29 |
DEBIT_NOTE("DN No:", "DEBIT NOTE DETAILS", "Total Debit Note Value", "debit note"),
|
|
|
30 |
CREDIT_NOTE("CN No:", "CREDIT NOTE DETAILS", "Total Credit Note Value", "credit note");
|
|
|
31 |
|
|
|
32 |
private final String numberLabel;
|
|
|
33 |
private final String sectionLabel;
|
|
|
34 |
private final String totalValueLabel;
|
|
|
35 |
private final String noun;
|
|
|
36 |
|
|
|
37 |
DocumentType(String numberLabel, String sectionLabel, String totalValueLabel, String noun) {
|
|
|
38 |
this.numberLabel = numberLabel;
|
|
|
39 |
this.sectionLabel = sectionLabel;
|
|
|
40 |
this.totalValueLabel = totalValueLabel;
|
|
|
41 |
this.noun = noun;
|
|
|
42 |
}
|
|
|
43 |
|
|
|
44 |
/** Label preceding the document number, e.g. "Invoice No:" / "DN No:". */
|
|
|
45 |
public String numberLabel() { return numberLabel; }
|
|
|
46 |
/** Right-aligned section heading, e.g. "INVOICE DETAILS". */
|
|
|
47 |
public String sectionLabel() { return sectionLabel; }
|
|
|
48 |
/** Grand-total row label, e.g. "Total Invoice Value". */
|
|
|
49 |
public String totalValueLabel() { return totalValueLabel; }
|
|
|
50 |
/** Lower-case noun for prose, e.g. "invoice" in "computer-generated invoice". */
|
|
|
51 |
public String noun() { return noun; }
|
|
|
52 |
}
|
|
|
53 |
|
|
|
54 |
private final InvoicePdfModel model;
|
|
|
55 |
private final DocumentType type;
|
|
|
56 |
private final String title;
|
|
|
57 |
private final String documentNumber;
|
|
|
58 |
private final String documentDate;
|
|
|
59 |
private final String originalInvoiceNumber;
|
|
|
60 |
private final String originalInvoiceDate;
|
|
|
61 |
|
| 37379 |
amit |
62 |
/** Memoized {@link #items()} result — insurance folding runs once per document. */
|
|
|
63 |
private List<CustomOrderItem> items;
|
|
|
64 |
private boolean itemsBuilt;
|
|
|
65 |
|
| 37066 |
amit |
66 |
public DocumentData(InvoicePdfModel model, DocumentType type, String title,
|
|
|
67 |
String documentNumber, String documentDate,
|
|
|
68 |
String originalInvoiceNumber, String originalInvoiceDate) {
|
|
|
69 |
this.model = model;
|
|
|
70 |
this.type = type;
|
|
|
71 |
this.title = title;
|
|
|
72 |
this.documentNumber = documentNumber;
|
|
|
73 |
this.documentDate = documentDate;
|
|
|
74 |
this.originalInvoiceNumber = originalInvoiceNumber;
|
|
|
75 |
this.originalInvoiceDate = originalInvoiceDate;
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
public InvoicePdfModel model() { return model; }
|
|
|
79 |
public DocumentType type() { return type; }
|
|
|
80 |
|
|
|
81 |
/** Upper-cased display title shown in the header banner (e.g. "TAX INVOICE", "DEBIT NOTE"). */
|
|
|
82 |
public String title() { return title; }
|
|
|
83 |
|
|
|
84 |
public String documentNumber() { return documentNumber; }
|
|
|
85 |
public String documentDate() { return documentDate; }
|
|
|
86 |
|
|
|
87 |
/** Original document reference shown on a note (e.g. supplier invoice no for a warehouse debit note); null on invoices. */
|
|
|
88 |
public String originalInvoiceNumber() { return originalInvoiceNumber; }
|
|
|
89 |
public String originalInvoiceDate() { return originalInvoiceDate; }
|
|
|
90 |
|
|
|
91 |
public boolean isNote() {
|
|
|
92 |
return type == DocumentType.DEBIT_NOTE || type == DocumentType.CREDIT_NOTE;
|
|
|
93 |
}
|
|
|
94 |
|
|
|
95 |
public CustomCustomer customer() { return model.getCustomer(); }
|
|
|
96 |
public CustomRetailer retailer() { return model.getRetailer(); }
|
| 37379 |
amit |
97 |
/**
|
|
|
98 |
* Printable lines: the order items followed by one line per insurance policy.
|
|
|
99 |
*
|
|
|
100 |
* <p>An extended-warranty / damage-protection policy is not a catalog item, so it has no
|
|
|
101 |
* {@code fofo_order_item} row and arrives on the model as a {@link CustomInsurancePolicy}
|
|
|
102 |
* instead. It is still a supply on the invoice and must be printed and taxed like any other
|
|
|
103 |
* line, so it is folded in here — at the single accessor every section reads — rather than in
|
|
|
104 |
* each section. Insurance sold after the device sale gets its own invoice, whose only line is
|
|
|
105 |
* the policy; without this the whole table (and therefore the totals) came out empty.
|
|
|
106 |
*/
|
|
|
107 |
public List<CustomOrderItem> items() {
|
|
|
108 |
if (!itemsBuilt) {
|
|
|
109 |
items = buildItems();
|
|
|
110 |
itemsBuilt = true;
|
|
|
111 |
}
|
|
|
112 |
return items;
|
|
|
113 |
}
|
|
|
114 |
|
|
|
115 |
private List<CustomOrderItem> buildItems() {
|
|
|
116 |
List<CustomInsurancePolicy> policies = model.getInsurancePolicies();
|
|
|
117 |
if (policies == null || policies.isEmpty()) {
|
|
|
118 |
// No policies: hand back the model's own list untouched so nothing else can shift.
|
|
|
119 |
return model.getOrderItems();
|
|
|
120 |
}
|
|
|
121 |
List<CustomOrderItem> combined = new ArrayList<>();
|
|
|
122 |
if (model.getOrderItems() != null) {
|
|
|
123 |
combined.addAll(model.getOrderItems());
|
|
|
124 |
}
|
|
|
125 |
boolean intraState = intraState();
|
|
|
126 |
for (CustomInsurancePolicy policy : policies) {
|
|
|
127 |
combined.add(toOrderItem(policy, intraState));
|
|
|
128 |
}
|
|
|
129 |
return combined;
|
|
|
130 |
}
|
|
|
131 |
|
|
|
132 |
/**
|
|
|
133 |
* Maps a policy onto a printable line, mirroring the columns the pre-refactor renderer emitted:
|
|
|
134 |
* quantity 1, no discount, the taxable value repeated in the Rate column, and only the tax side
|
|
|
135 |
* that applies to this supply populated — matching how real order items are built, so the
|
|
|
136 |
* margin-scheme rate column (which sums all three tax amounts) stays correct.
|
|
|
137 |
*/
|
|
|
138 |
private static CustomOrderItem toOrderItem(CustomInsurancePolicy policy, boolean intraState) {
|
|
|
139 |
CustomOrderItem item = new CustomOrderItem();
|
|
|
140 |
item.setDescription(policy.getDescription());
|
|
|
141 |
item.setHsnCode(policy.getHsnCode());
|
|
|
142 |
item.setQuantity(1);
|
|
|
143 |
item.setRate(policy.getRate());
|
|
|
144 |
item.setDiscount(0f);
|
|
|
145 |
item.setAmount(policy.getRate());
|
|
|
146 |
item.setNetAmount(policy.getNetAmount());
|
|
|
147 |
if (intraState) {
|
|
|
148 |
item.setCgstRate(policy.getCgstRate());
|
|
|
149 |
item.setCgstAmount(policy.getCgstAmount());
|
|
|
150 |
item.setSgstRate(policy.getSgstRate());
|
|
|
151 |
item.setSgstAmount(policy.getSgstAmount());
|
|
|
152 |
} else {
|
|
|
153 |
item.setIgstRate(policy.getIgstRate());
|
|
|
154 |
item.setIgstAmount(policy.getIgstAmount());
|
|
|
155 |
}
|
|
|
156 |
return item;
|
|
|
157 |
}
|
|
|
158 |
|
| 37066 |
amit |
159 |
public List<CustomPaymentOption> paymentOptions() { return model.getPaymentOptions(); }
|
|
|
160 |
public List<String> creditTerms() { return model.getCreditTerms(); }
|
|
|
161 |
public IrnModel irnModel() { return model.getIrnModel(); }
|
|
|
162 |
public String irnErrorMessage() { return model.getIrnErrorMessage(); }
|
|
|
163 |
public EWayBillPdfModel eWayBill() { return model.geteWayBillPdfModel(); }
|
|
|
164 |
public boolean isCancelled() { return model.isCancelled(); }
|
|
|
165 |
public boolean isMargin() { return model.isHasMarginSchemeItems(); }
|
|
|
166 |
public String customerAddressStateCode() { return model.getCustomerAddressStateCode(); }
|
|
|
167 |
public String partnerAddressStateCode() { return model.getPartnerAddressStateCode(); }
|
|
|
168 |
|
|
|
169 |
/** Mapped purchase-order number (transaction.order only); null when unmapped — then not printed. */
|
|
|
170 |
public String poNumber() { return model.getPoNumber(); }
|
|
|
171 |
|
|
|
172 |
/** Order placed date; printed whenever present. */
|
|
|
173 |
public String orderDate() { return model.getOrderDate(); }
|
|
|
174 |
|
|
|
175 |
/** Intra-state supply iff buyer and supplier are in the same state. Mirrors the legacy rule. */
|
|
|
176 |
public boolean intraState() {
|
|
|
177 |
return customer().getAddress().getState().equals(retailer().getAddress().getState());
|
|
|
178 |
}
|
|
|
179 |
|
|
|
180 |
/** State code printed in the supplier block — buyer's for intra-state, partner's for inter-state. */
|
|
|
181 |
public String stateCode() {
|
|
|
182 |
return intraState() ? customerAddressStateCode() : partnerAddressStateCode();
|
|
|
183 |
}
|
|
|
184 |
|
|
|
185 |
/** True when any line carries an order id, which adds the "Order Id" column. */
|
|
|
186 |
public boolean showOrderId() {
|
|
|
187 |
if (items() == null) return false;
|
|
|
188 |
for (CustomOrderItem item : items()) {
|
|
|
189 |
if (item.getOrderId() != 0) return true;
|
|
|
190 |
}
|
|
|
191 |
return false;
|
|
|
192 |
}
|
|
|
193 |
}
|