| Line 1... |
Line 1... |
| 1 |
package com.smartdukaan.cron.migrations;
|
1 |
package com.smartdukaan.cron.migrations;
|
| 2 |
|
2 |
|
| 3 |
import com.spice.profitmandi.common.enumuration.FofoType;
|
3 |
import com.spice.profitmandi.common.enumuration.FofoType;
|
| 4 |
import com.spice.profitmandi.common.enumuration.ItemType;
|
4 |
import com.spice.profitmandi.common.enumuration.ItemType;
|
| 5 |
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
|
5 |
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
|
| 6 |
import com.spice.profitmandi.common.model.PORowModel;
|
6 |
import com.spice.profitmandi.common.model.GrnModel;
|
| - |
|
7 |
import com.spice.profitmandi.common.model.InvoiceItemModel;
|
| - |
|
8 |
import com.spice.profitmandi.common.model.WarehouseInvoiceModel;
|
| - |
|
9 |
import com.spice.profitmandi.dao.entity.auth.AuthUser;
|
| 7 |
import com.spice.profitmandi.dao.entity.catalog.Item;
|
10 |
import com.spice.profitmandi.dao.entity.catalog.Item;
|
| 8 |
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
|
11 |
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
|
| 9 |
import com.spice.profitmandi.dao.entity.transaction.LineItem;
|
12 |
import com.spice.profitmandi.dao.entity.transaction.LineItem;
|
| 10 |
import com.spice.profitmandi.dao.entity.transaction.Order;
|
13 |
import com.spice.profitmandi.dao.entity.transaction.Order;
|
| 11 |
import com.spice.profitmandi.dao.entity.warehouse.WarehousePurchaseOrder;
|
14 |
import com.spice.profitmandi.dao.entity.warehouse.WarehousePurchaseOrder;
|
| 12 |
import com.spice.profitmandi.dao.entity.warehouse.WarehouseSupplierInvoice;
|
15 |
import com.spice.profitmandi.dao.entity.warehouse.WarehouseSupplierInvoice;
|
| - |
|
16 |
import com.spice.profitmandi.dao.enumuration.warehouse.WarehouseInvoiceStatus;
|
| - |
|
17 |
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
|
| 13 |
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
|
18 |
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
|
| 14 |
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
|
19 |
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
|
| 15 |
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
|
20 |
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
|
| 16 |
import com.spice.profitmandi.dao.repository.warehouse.WarehousePurchaseOrderRepository;
|
21 |
import com.spice.profitmandi.dao.repository.warehouse.WarehousePurchaseOrderRepository;
|
| 17 |
import com.spice.profitmandi.dao.repository.warehouse.WarehouseSupplierInvoiceRepository;
|
22 |
import com.spice.profitmandi.dao.repository.warehouse.WarehouseSupplierInvoiceRepository;
|
| - |
|
23 |
import com.spice.profitmandi.service.warehouse.InvoiceService;
|
| 18 |
import com.spice.profitmandi.service.warehouse.PurchaseOrderService;
|
24 |
import com.spice.profitmandi.service.warehouse.PurchaseOrderService;
|
| 19 |
import org.apache.logging.log4j.LogManager;
|
25 |
import org.apache.logging.log4j.LogManager;
|
| 20 |
import org.apache.logging.log4j.Logger;
|
26 |
import org.apache.logging.log4j.Logger;
|
| 21 |
import org.springframework.beans.factory.annotation.Autowired;
|
27 |
import org.springframework.beans.factory.annotation.Autowired;
|
| 22 |
import org.springframework.stereotype.Component;
|
28 |
import org.springframework.stereotype.Component;
|
| Line 26... |
Line 32... |
| 26 |
import java.math.BigDecimal;
|
32 |
import java.math.BigDecimal;
|
| 27 |
import java.time.LocalDateTime;
|
33 |
import java.time.LocalDateTime;
|
| 28 |
import java.util.ArrayList;
|
34 |
import java.util.ArrayList;
|
| 29 |
import java.util.Collections;
|
35 |
import java.util.Collections;
|
| 30 |
import java.util.HashSet;
|
36 |
import java.util.HashSet;
|
| - |
|
37 |
import java.util.LinkedHashMap;
|
| 31 |
import java.util.List;
|
38 |
import java.util.List;
|
| 32 |
import java.util.Map;
|
39 |
import java.util.Map;
|
| 33 |
import java.util.Set;
|
40 |
import java.util.Set;
|
| 34 |
|
41 |
|
| 35 |
/**
|
42 |
/**
|
| 36 |
* Receives one internal transfer invoice into the destination warehouse.
|
43 |
* Receives one internal transfer invoice into the destination warehouse, following the same sequence the
|
| - |
|
44 |
* portal performs: record the supplier invoice, record its items, then GRN it through
|
| - |
|
45 |
* PurchaseOrderService.grnPoModels - the call behind the portal's Create GRN button.
|
| - |
|
46 |
*
|
| - |
|
47 |
* The Excel upload path (addPORowModels) is deliberately not used. It persists a supplier invoice without a
|
| - |
|
48 |
* status, which the column does not allow, so that route cannot complete a receipt at all.
|
| 37 |
*
|
49 |
*
|
| 38 |
* Kept in its own bean on purpose: InternalGrnTask calls this through the Spring proxy, so the transaction
|
50 |
* Kept in its own bean on purpose: InternalGrnTask calls this through the Spring proxy, so the transaction
|
| 39 |
* below is actually applied. Calling it from inside the driver would be a self invocation, the proxy would
|
51 |
* below is actually applied. Calling it from inside the driver would be a self invocation, the proxy would
|
| 40 |
* be bypassed and the work would run with no transaction at all.
|
52 |
* be bypassed and the work would run with no transaction at all.
|
| 41 |
*/
|
53 |
*/
|
| 42 |
@Component
|
54 |
@Component
|
| 43 |
public class InternalGrnReceiver {
|
55 |
public class InternalGrnReceiver {
|
| 44 |
|
56 |
|
| 45 |
private static final Logger LOGGER = LogManager.getLogger(InternalGrnReceiver.class);
|
57 |
private static final Logger LOGGER = LogManager.getLogger(InternalGrnReceiver.class);
|
| 46 |
|
58 |
|
| - |
|
59 |
/** The portal stores the scanned supplier invoice against the receipt; an internal transfer has none. */
|
| - |
|
60 |
private static final int NO_INVOICE_DOCUMENT = 0;
|
| - |
|
61 |
|
| 47 |
@Autowired
|
62 |
@Autowired
|
| 48 |
private OrderRepository orderRepository;
|
63 |
private OrderRepository orderRepository;
|
| 49 |
|
64 |
|
| 50 |
@Autowired
|
65 |
@Autowired
|
| 51 |
private ItemRepository itemRepository;
|
66 |
private ItemRepository itemRepository;
|
| 52 |
|
67 |
|
| 53 |
@Autowired
|
68 |
@Autowired
|
| 54 |
private FofoStoreRepository fofoStoreRepository;
|
69 |
private FofoStoreRepository fofoStoreRepository;
|
| 55 |
|
70 |
|
| 56 |
@Autowired
|
71 |
@Autowired
|
| - |
|
72 |
private AuthRepository authRepository;
|
| - |
|
73 |
|
| - |
|
74 |
@Autowired
|
| 57 |
private WarehousePurchaseOrderRepository warehousePurchaseOrderRepository;
|
75 |
private WarehousePurchaseOrderRepository warehousePurchaseOrderRepository;
|
| 58 |
|
76 |
|
| 59 |
@Autowired
|
77 |
@Autowired
|
| 60 |
private WarehouseSupplierInvoiceRepository warehouseSupplierInvoiceRepository;
|
78 |
private WarehouseSupplierInvoiceRepository warehouseSupplierInvoiceRepository;
|
| 61 |
|
79 |
|
| 62 |
@Autowired
|
80 |
@Autowired
|
| - |
|
81 |
private InvoiceService invoiceService;
|
| - |
|
82 |
|
| - |
|
83 |
@Autowired
|
| 63 |
private PurchaseOrderService purchaseOrderService;
|
84 |
private PurchaseOrderService purchaseOrderService;
|
| 64 |
|
85 |
|
| - |
|
86 |
/** One item of an invoice, gathered across the orders that share it. */
|
| - |
|
87 |
private static class ReceiptLine {
|
| - |
|
88 |
private int itemId;
|
| - |
|
89 |
private boolean serialized;
|
| - |
|
90 |
private float rate;
|
| - |
|
91 |
private int qty;
|
| - |
|
92 |
private final List<String> serialNumbers = new ArrayList<>();
|
| - |
|
93 |
}
|
| - |
|
94 |
|
| 65 |
/**
|
95 |
/**
|
| 66 |
* Each invoice commits or rolls back on its own so one bad invoice cannot undo those already received.
|
96 |
* Each invoice commits or rolls back on its own so one bad invoice cannot undo those already received.
|
| 67 |
*
|
97 |
*
|
| 68 |
* @return true when the invoice was received (or would be, on a dry run), false when it was skipped.
|
98 |
* @return true when the invoice was received (or would be, on a dry run), false when it was skipped.
|
| 69 |
*/
|
99 |
*/
|
| Line 80... |
Line 110... |
| 80 |
if (buyer == null || !FofoType.INTERNAL.equals(buyer.getFofoType())) {
|
110 |
if (buyer == null || !FofoType.INTERNAL.equals(buyer.getFofoType())) {
|
| 81 |
LOGGER.info("SKIP {} - buyer {} is not an INTERNAL store", invoiceNumber, orders.get(0).getRetailerId());
|
111 |
LOGGER.info("SKIP {} - buyer {} is not an INTERNAL store", invoiceNumber, orders.get(0).getRetailerId());
|
| 82 |
return false;
|
112 |
return false;
|
| 83 |
}
|
113 |
}
|
| 84 |
|
114 |
|
| 85 |
// An internal PO reaches its orders through the transaction it raised, not through order.purchase_order_id.
|
- |
|
| 86 |
Set<Integer> transactionIds = new HashSet<>();
|
- |
|
| 87 |
for (Order order : orders) {
|
- |
|
| 88 |
transactionIds.add(order.getTransactionId());
|
- |
|
| 89 |
}
|
- |
|
| 90 |
Set<Integer> poIds = new HashSet<>();
|
- |
|
| 91 |
WarehousePurchaseOrder purchaseOrder = null;
|
115 |
WarehousePurchaseOrder purchaseOrder = resolvePurchaseOrder(invoiceNumber, orders);
|
| 92 |
for (Integer transactionId : transactionIds) {
|
- |
|
| 93 |
WarehousePurchaseOrder po = warehousePurchaseOrderRepository.selectByTransactionId(transactionId);
|
- |
|
| 94 |
if (po != null && poIds.add(po.getId())) {
|
- |
|
| 95 |
purchaseOrder = po;
|
- |
|
| 96 |
}
|
- |
|
| 97 |
}
|
- |
|
| 98 |
if (purchaseOrder == null) {
|
116 |
if (purchaseOrder == null) {
|
| 99 |
LOGGER.info("SKIP {} - no purchase order found for transaction(s) {}", invoiceNumber, transactionIds);
|
- |
|
| 100 |
return false;
|
- |
|
| 101 |
}
|
- |
|
| 102 |
// addPORowModels resolves a single PO for the whole map, so an invoice spanning POs cannot be trusted to it.
|
- |
|
| 103 |
if (poIds.size() > 1) {
|
- |
|
| 104 |
LOGGER.info("SKIP {} - spans {} purchase orders {}", invoiceNumber, poIds.size(), poIds);
|
- |
|
| 105 |
return false;
|
117 |
return false;
|
| 106 |
}
|
118 |
}
|
| 107 |
|
119 |
|
| 108 |
WarehouseSupplierInvoice existing = warehouseSupplierInvoiceRepository
|
120 |
WarehouseSupplierInvoice existing = warehouseSupplierInvoiceRepository
|
| 109 |
.selectAllBySupplierInvoice(purchaseOrder.getSupplierId(), invoiceNumber);
|
121 |
.selectAllBySupplierInvoice(purchaseOrder.getSupplierId(), invoiceNumber);
|
| Line 111... |
Line 123... |
| 111 |
LOGGER.info("SKIP {} - already received (invoice id {}, status {})",
|
123 |
LOGGER.info("SKIP {} - already received (invoice id {}, status {})",
|
| 112 |
invoiceNumber, existing.getId(), existing.getStatus());
|
124 |
invoiceNumber, existing.getId(), existing.getStatus());
|
| 113 |
return false;
|
125 |
return false;
|
| 114 |
}
|
126 |
}
|
| 115 |
|
127 |
|
| 116 |
LocalDateTime receivedDate = LocalDateTime.now();
|
128 |
// grnPoModels takes one entry per item, carrying every serial of that item, so gather the orders by item.
|
| 117 |
List<PORowModel> rows = new ArrayList<>();
|
129 |
Map<Integer, ReceiptLine> linesByItem = new LinkedHashMap<>();
|
| 118 |
BigDecimal value = BigDecimal.ZERO;
|
- |
|
| 119 |
int serials = 0;
|
- |
|
| 120 |
for (Order order : orders) {
|
130 |
for (Order order : orders) {
|
| 121 |
LineItem lineItem = order.getLineItem();
|
131 |
LineItem lineItem = order.getLineItem();
|
| 122 |
if (lineItem == null) {
|
132 |
if (lineItem == null) {
|
| 123 |
LOGGER.info("SKIP {} - order {} has no line item", invoiceNumber, order.getId());
|
133 |
LOGGER.info("SKIP {} - order {} has no line item", invoiceNumber, order.getId());
|
| 124 |
return false;
|
134 |
return false;
|
| Line 135... |
Line 145... |
| 135 |
if (serialized && (serialNumber == null || serialNumber.trim().isEmpty())) {
|
145 |
if (serialized && (serialNumber == null || serialNumber.trim().isEmpty())) {
|
| 136 |
LOGGER.info("SKIP {} - serialized item {} on order {} has no serial number",
|
146 |
LOGGER.info("SKIP {} - serialized item {} on order {} has no serial number",
|
| 137 |
invoiceNumber, item.getId(), order.getId());
|
147 |
invoiceNumber, item.getId(), order.getId());
|
| 138 |
return false;
|
148 |
return false;
|
| 139 |
}
|
149 |
}
|
| - |
|
150 |
|
| - |
|
151 |
ReceiptLine line = linesByItem.get(lineItem.getItemId());
|
| - |
|
152 |
if (line == null) {
|
| - |
|
153 |
line = new ReceiptLine();
|
| - |
|
154 |
line.itemId = lineItem.getItemId();
|
| - |
|
155 |
line.serialized = serialized;
|
| - |
|
156 |
line.rate = lineItem.getUnitPrice();
|
| - |
|
157 |
linesByItem.put(line.itemId, line);
|
| - |
|
158 |
}
|
| - |
|
159 |
line.qty += lineItem.getQuantity();
|
| 140 |
if (serialized) {
|
160 |
if (serialized) {
|
| 141 |
serials++;
|
161 |
line.serialNumbers.add(serialNumber.trim());
|
| 142 |
}
|
162 |
}
|
| - |
|
163 |
}
|
| 143 |
|
164 |
|
| 144 |
PORowModel row = new PORowModel();
|
165 |
int numItems = 0;
|
| 145 |
row.setPoNumber(purchaseOrder.getPoNumber());
|
- |
|
| 146 |
row.setInvoiceNumber(invoiceNumber);
|
166 |
int serialisedUnits = 0;
|
| 147 |
row.setInvoiceDate(order.getBillingTimestamp());
|
- |
|
| 148 |
row.setReceivedDate(receivedDate);
|
167 |
BigDecimal value = BigDecimal.ZERO;
|
| 149 |
row.setItemId(lineItem.getItemId());
|
168 |
for (ReceiptLine line : linesByItem.values()) {
|
| 150 |
row.setQuantity(lineItem.getQuantity());
|
169 |
numItems += line.qty;
|
| 151 |
row.setUnitPrice(lineItem.getUnitPrice());
|
170 |
serialisedUnits += line.serialNumbers.size();
|
| 152 |
row.setImeiNumber(serialized ? serialNumber.trim() : null);
|
- |
|
| 153 |
rows.add(row);
|
- |
|
| 154 |
|
- |
|
| 155 |
value = value.add(BigDecimal.valueOf(lineItem.getUnitPrice())
|
171 |
value = value.add(BigDecimal.valueOf(line.rate).multiply(BigDecimal.valueOf(line.qty)));
|
| 156 |
.multiply(BigDecimal.valueOf(lineItem.getQuantity())));
|
- |
|
| 157 |
}
|
172 |
}
|
| 158 |
|
173 |
|
| 159 |
if (dryRun) {
|
174 |
if (dryRun) {
|
| 160 |
LOGGER.info("WOULD GRN {} - po {} (id {}), warehouse {}, supplier {}, {} line(s), {} serialized, value {}, receivedDate {}",
|
175 |
LOGGER.info("WOULD GRN {} - po {} (id {}), warehouse {}, supplier {}, {} item(s), {} unit(s), {} serialized, value {}",
|
| 161 |
invoiceNumber, purchaseOrder.getPoNumber(), purchaseOrder.getId(), purchaseOrder.getWarehouseId(),
|
176 |
invoiceNumber, purchaseOrder.getPoNumber(), purchaseOrder.getId(), purchaseOrder.getWarehouseId(),
|
| 162 |
purchaseOrder.getSupplierId(), rows.size(), serials, value.toPlainString(), receivedDate);
|
177 |
purchaseOrder.getSupplierId(), linesByItem.size(), numItems, serialisedUnits, value.toPlainString());
|
| 163 |
for (PORowModel row : rows) {
|
178 |
for (ReceiptLine line : linesByItem.values()) {
|
| 164 |
LOGGER.info(" item {} qty {} price {} serial {}",
|
179 |
LOGGER.info(" item {} qty {} rate {} serials {}",
|
| 165 |
row.getItemId(), row.getQuantity(), row.getUnitPrice(),
|
180 |
line.itemId, line.qty, line.rate,
|
| 166 |
row.getImeiNumber() == null ? "-" : row.getImeiNumber());
|
181 |
line.serialNumbers.isEmpty() ? "-" : line.serialNumbers);
|
| 167 |
}
|
182 |
}
|
| 168 |
return true;
|
183 |
return true;
|
| 169 |
}
|
184 |
}
|
| 170 |
|
185 |
|
| - |
|
186 |
// 1. Record the supplier invoice, as the portal's Receive Invoice screen does.
|
| - |
|
187 |
AuthUser operator = authRepository.selectByEmailOrMobile(operatorEmail);
|
| - |
|
188 |
WarehouseSupplierInvoice invoice = new WarehouseSupplierInvoice();
|
| - |
|
189 |
invoice.setInvoiceNumber(invoiceNumber);
|
| - |
|
190 |
invoice.setInvoiceDate(orders.get(0).getBillingTimestamp());
|
| - |
|
191 |
invoice.setSupplierId(purchaseOrder.getSupplierId());
|
| - |
|
192 |
invoice.setWarehouseId(purchaseOrder.getWarehouseId());
|
| - |
|
193 |
invoice.setCreateDate(LocalDateTime.now());
|
| - |
|
194 |
invoice.setReceivedFrom(operator.getFullName());
|
| - |
|
195 |
invoice.setNumItems(numItems);
|
| - |
|
196 |
invoice.setTotalValue(value.floatValue());
|
| - |
|
197 |
invoice.setStatus(WarehouseInvoiceStatus.init);
|
| - |
|
198 |
invoice.setInvoiceDocId(NO_INVOICE_DOCUMENT);
|
| - |
|
199 |
warehouseSupplierInvoiceRepository.persist(invoice);
|
| - |
|
200 |
|
| 171 |
// One PO and one invoice per call - addPORowModels applies the first PO it resolves to every entry.
|
201 |
// 2. Record its items, as the Add Item screen does - the buying reports read these rows.
|
| - |
|
202 |
WarehouseInvoiceModel invoiceModel = new WarehouseInvoiceModel();
|
| - |
|
203 |
invoiceModel.setInvoiceId(invoice.getId());
|
| - |
|
204 |
invoiceModel.setSupplierId(purchaseOrder.getSupplierId());
|
| - |
|
205 |
invoiceModel.setWarehouseId(purchaseOrder.getWarehouseId());
|
| - |
|
206 |
List<InvoiceItemModel> invoiceItems = new ArrayList<>();
|
| - |
|
207 |
for (ReceiptLine line : linesByItem.values()) {
|
| - |
|
208 |
InvoiceItemModel invoiceItem = new InvoiceItemModel();
|
| - |
|
209 |
invoiceItem.setItemId(line.itemId);
|
| - |
|
210 |
invoiceItem.setQty(line.qty);
|
| - |
|
211 |
invoiceItem.setRate(line.rate);
|
| - |
|
212 |
invoiceItems.add(invoiceItem);
|
| - |
|
213 |
}
|
| - |
|
214 |
invoiceModel.setInvoiceItems(invoiceItems);
|
| - |
|
215 |
invoiceService.createInvoiceItem(invoiceModel);
|
| - |
|
216 |
|
| - |
|
217 |
// 3. GRN it, exactly as the portal's Create GRN button does.
|
| - |
|
218 |
List<GrnModel> grnModels = new ArrayList<>();
|
| - |
|
219 |
for (ReceiptLine line : linesByItem.values()) {
|
| - |
|
220 |
GrnModel grnModel = new GrnModel();
|
| - |
|
221 |
grnModel.setPoId(purchaseOrder.getId());
|
| - |
|
222 |
grnModel.setInvoiceId(invoice.getId());
|
| - |
|
223 |
grnModel.setItemId(line.itemId);
|
| - |
|
224 |
grnModel.setQty(line.qty);
|
| - |
|
225 |
grnModel.setInvoicePrice(line.rate);
|
| - |
|
226 |
grnModel.setSerialNumbers(line.serialized ? line.serialNumbers : new ArrayList<String>());
|
| - |
|
227 |
grnModels.add(grnModel);
|
| - |
|
228 |
}
|
| 172 |
Map<String, Map<String, List<PORowModel>>> poRowModelsMap = Collections.singletonMap(
|
229 |
Map<Integer, Map<Integer, List<GrnModel>>> grnModelsMap = Collections.singletonMap(
|
| 173 |
purchaseOrder.getPoNumber(), Collections.singletonMap(invoiceNumber, rows));
|
230 |
purchaseOrder.getId(), Collections.singletonMap(invoice.getId(), grnModels));
|
| 174 |
purchaseOrderService.addPORowModels(operatorEmail, poRowModelsMap);
|
231 |
purchaseOrderService.grnPoModels(operatorEmail, grnModelsMap);
|
| 175 |
|
232 |
|
| 176 |
LOGGER.info("GRNED {} - po {}, warehouse {}, {} line(s), {} serialized, value {}",
|
233 |
LOGGER.info("GRNED {} - po {}, warehouse {}, invoice id {}, {} item(s), {} unit(s), {} serialized, value {}",
|
| 177 |
invoiceNumber, purchaseOrder.getPoNumber(), purchaseOrder.getWarehouseId(),
|
234 |
invoiceNumber, purchaseOrder.getPoNumber(), purchaseOrder.getWarehouseId(), invoice.getId(),
|
| 178 |
rows.size(), serials, value.toPlainString());
|
235 |
linesByItem.size(), numItems, serialisedUnits, value.toPlainString());
|
| 179 |
return true;
|
236 |
return true;
|
| 180 |
}
|
237 |
}
|
| - |
|
238 |
|
| - |
|
239 |
/**
|
| - |
|
240 |
* Creating an internal PO raises one transaction and records it on the order
|
| - |
|
241 |
* (PurchaseOrderServiceImpl: warehousePurchaseOrder.setTransactionId), so that is the mapping back from
|
| - |
|
242 |
* an invoice to its PO. order.purchase_order_id is not it - nothing populates it on this route.
|
| - |
|
243 |
*
|
| - |
|
244 |
* The invoice's orders all belong to that one transaction; if they ever did not, the PO is ambiguous and
|
| - |
|
245 |
* the invoice is left alone rather than guessed at.
|
| - |
|
246 |
*/
|
| - |
|
247 |
private WarehousePurchaseOrder resolvePurchaseOrder(String invoiceNumber, List<Order> orders) {
|
| - |
|
248 |
Set<Integer> transactionIds = new HashSet<>();
|
| - |
|
249 |
for (Order order : orders) {
|
| - |
|
250 |
transactionIds.add(order.getTransactionId());
|
| - |
|
251 |
}
|
| - |
|
252 |
if (transactionIds.size() > 1) {
|
| - |
|
253 |
LOGGER.info("SKIP {} - spans {} transactions {}", invoiceNumber, transactionIds.size(), transactionIds);
|
| - |
|
254 |
return null;
|
| - |
|
255 |
}
|
| - |
|
256 |
int transactionId = transactionIds.iterator().next();
|
| - |
|
257 |
WarehousePurchaseOrder purchaseOrder = warehousePurchaseOrderRepository.selectByTransactionId(transactionId);
|
| - |
|
258 |
if (purchaseOrder == null) {
|
| - |
|
259 |
LOGGER.info("SKIP {} - no purchase order mapped to transaction {}", invoiceNumber, transactionId);
|
| - |
|
260 |
return null;
|
| - |
|
261 |
}
|
| - |
|
262 |
return purchaseOrder;
|
| - |
|
263 |
}
|
| 181 |
}
|
264 |
}
|