Untitled

 avatar
unknown
kotlin
a year ago
3.6 kB
7
Indexable
//looks scary but it works
            //point is that order have lines, lines have items
            //line can be dispatched or preparing and we have info only about dispatched lines
            orders.forEach { order ->
                val orderEntity = order.getOrder(store)
                //1. insert order and clear all data that were associated with this order
                repository.insertOrder(orderEntity)
                repository.clearOrderItemsByOrderId(order.id)
                repository.clearOrderLinesByOrderId(order.id)

                //2. get dispatched lines that were given from backend
                val dispatchedLines = order.getDispatchedOrderLines(order.id)
                val dispatchedQuantity = order.successfulFulfillments.sumOf { it.orderLine.fulfillmentLineItems.sumOf { it.quantity } }
                val fullQuantity = order.lineItems.sumOf { it.orderItemInfo.quantity }

                //3. check if items count in dispatched lines equal to order items size
                //if not, we have to add preparing line to the end
                val lines = if (fullQuantity != dispatchedQuantity) {
                    val preparingLine = OrderLine(
                        orderId = order.id,
                        dispatched = false
                    )
                    dispatchedLines + preparingLine
                } else dispatchedLines
                //4. cache lines to receive their ids from room, because lines don't have ids from backend
                val insertedLinesIds = repository.insertOrderLines(lines).map { it.toInt() }

                //5. append dict of items to their quantity
                val totalItemsQuantityMap = mutableMapOf<String, Int>()
                order.lineItems.forEach {
                    totalItemsQuantityMap[it.orderItemInfo.storeId] = it.orderItemInfo.quantity
                }
                val orderItemInfoList = order.lineItems.map { it.orderItemInfo }

                //6. associate dispatched lines from backend with ids that received from room
                //and get item entities with their lines
                val orderItems = order.successfulFulfillments.zip(insertedLinesIds) { line, lineId ->
                    line.orderLine.fulfillmentLineItems.mapNotNull {
                        val storeId = it.lineItem.storeId
                        val quantity = it.quantity
                        val item = orderItemInfoList.firstOrNull { it.storeId == storeId } ?: return@mapNotNull null
                        //7. decrease quantity in dict from items that contains in dispatched lines
                        totalItemsQuantityMap[storeId]?.let {
                            totalItemsQuantityMap[storeId] = it - quantity
                        }
                        item.getOrderItem(order.id, lineId, quantity)
                    }
                }.flatten().toMutableList()
                //8. if dict not empty that's mean that some items in preparing status
                //add them to preparing line
                if (totalItemsQuantityMap.filter { it.value > 0  }.isNotEmpty()) {
                    orderItems.addAll(totalItemsQuantityMap.filter { it.value > 0  }.mapNotNull {
                        val storeId = it.key
                        val item = orderItemInfoList.firstOrNull { it.storeId == storeId } ?: return@mapNotNull null
                        item.getOrderItem(order.id, insertedLinesIds.last(), it.value)
                    })
                }
                //9. finally, cache order items
                repository.insertOrderItems(orderItems)
Editor is loading...
Leave a Comment