Subversion Repositories SmartDukaan

Rev

Rev 37825 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.smartdukaan.cron.migrations;

import com.spice.profitmandi.dao.entity.warehouse.WarehousePurchaseOrder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * Bills internal movement transactions one at a time through MovementBiller. Like InternalGrnTask it carries no
 * transaction of its own, so each transaction bills (or fails) on its own and a self invocation never skips the proxy.
 */
@Component
public class MovementBillingTask {

    private static final Logger LOGGER = LogManager.getLogger(MovementBillingTask.class);

    @Autowired
    private MovementBiller movementBiller;

    public void billMovements(List<String> poNumbers, String operatorEmail,
                              int logisticsProviderId, boolean live) {
        Set<Integer> transactions = new LinkedHashSet<>();
        for (WarehousePurchaseOrder po : movementBiller.purchaseOrders(poNumbers)) {
            if (po.getTransactionId() == null) {
                LOGGER.warn("SKIPPED  PO {} raised no internal order (no transaction)", po.getPoNumber());
            } else {
                transactions.add(po.getTransactionId());
            }
        }
        LOGGER.info("=== Movement billing {} : {} transaction(s), operator {}, logistics provider {} ===",
                live ? "LIVE RUN" : "DRY RUN (no writes)", transactions.size(), operatorEmail, logisticsProviderId);

        List<String> invoices = new ArrayList<>();
        int ready = 0;
        int blocked = 0;
        int failed = 0;
        for (Integer transactionId : transactions) {
            try {
                MovementBiller.Plan plan = movementBiller.describe(transactionId);
                this.log(plan);
                if (!plan.problems.isEmpty()) {
                    blocked++;
                    continue;
                }
                if (!live) {
                    ready++;
                    continue;
                }
                invoices.add(movementBiller.bill(transactionId, operatorEmail, logisticsProviderId));
                ready++;
            } catch (Exception e) {
                failed++;
                LOGGER.error("FAILED   txn {} - {}", transactionId, e.getMessage(), e);
            }
        }
        LOGGER.info("=== Movement billing {} complete : {} {}, {} blocked, {} failed ===", live ? "LIVE RUN" : "DRY RUN",
                ready, live ? "billed" : "ready to bill", blocked, failed);
        if (!invoices.isEmpty()) {
            LOGGER.info("Invoices for --autoGrnInternal: --invoices={}", String.join(",", invoices));
        }
    }

    private void log(MovementBiller.Plan plan) {
        LOGGER.info("txn {} PO {} : {} -> {} : {} line(s), {} unit(s){}", plan.transactionId, plan.poNumber,
                plan.sourceWarehouseId, plan.destinationWarehouseId, plan.lines.size(),
                plan.lines.stream().mapToInt(x -> x.qty).sum(), plan.problems.isEmpty() ? "" : " - BLOCKED");
        for (MovementBiller.Line line : plan.lines) {
            LOGGER.info("   order {} {} x{} from {}{}{}", line.orderId, line.item, line.qty, line.fromWarehouseId,
                    line.repoint ? " (re-pointed from Dummy)" : "",
                    line.serialized ? " IMEIs " + String.join(",", line.imeis) : "");
        }
        for (String problem : plan.problems) {
            LOGGER.warn("   PROBLEM {}", problem);
        }
    }
}