Subversion Repositories SmartDukaan

Rev

Blame | Last modification | View Log | RSS feed

package com.spice.profitmandi.service.order;

import com.spice.profitmandi.common.model.CustomInsurancePolicy;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.dao.entity.dtr.InsurancePolicy;

import java.util.ArrayList;
import java.util.List;

/**
 * Builds the printable invoice line for an extended-warranty / damage-protection policy.
 *
 * <p>A policy is not a catalog item, so it has no {@code fofo_order_item} row; it reaches the PDF
 * as a {@link CustomInsurancePolicy} and is folded into the item table by
 * {@code DocumentData.items()}. Two invoices can carry one: the partner sale invoice
 * ({@link OrderServiceImpl#getInvoicePdfModel}) when the policy was sold alongside the device, and
 * the standalone invoice raised on behalf of the provider when it was sold on its own. Both build
 * the line here so the SAC, tax split and description cannot drift apart.
 */
public final class InsuranceInvoiceLine {

    /** SAC for insurance services. */
    private static final String SAC_CODE = "998716";

    /** Printed when the policy carries no plan name of its own. */
    private static final String DEFAULT_PLAN = "Damage Protection Plan";

    private InsuranceInvoiceLine() {
    }

    public static List<CustomInsurancePolicy> from(List<InsurancePolicy> policies) {
        List<CustomInsurancePolicy> lines = new ArrayList<>();
        if (policies == null) {
            return lines;
        }
        for (InsurancePolicy policy : policies) {
            lines.add(from(policy));
        }
        return lines;
    }

    /**
     * The policy is sold tax-inclusive, so the sale amount is grossed down to the taxable value and
     * both the inter-state and intra-state tax sides are populated; the renderer keeps whichever
     * applies to the supply and drops the other.
     */
    public static CustomInsurancePolicy from(InsurancePolicy policy) {
        float taxRate = ProfitMandiConstants.INSURANCE_TAX_RATE;
        float halfRate = taxRate / 2;
        float taxableAmount = policy.getSaleAmount() / (1 + taxRate / 100);

        CustomInsurancePolicy line = new CustomInsurancePolicy();
        line.setDescription(description(policy));
        line.setHsnCode(SAC_CODE);
        line.setRate(taxableAmount);
        line.setIgstRate(taxRate);
        line.setIgstAmount(taxableAmount * taxRate / 100);
        line.setCgstRate(halfRate);
        line.setCgstAmount(taxableAmount * halfRate / 100);
        line.setSgstRate(halfRate);
        line.setSgstAmount(taxableAmount * halfRate / 100);
        line.setNetAmount(policy.getSaleAmount());
        return line;
    }

    /**
     * {@code policyPlan} is only populated when the policy was sold through a plan-quote flow;
     * policies sold on their own leave it null, so fall back to the generic plan name rather than
     * printing "null" on a tax document.
     */
    private static String description(InsurancePolicy policy) {
        String plan = policy.getPolicyPlan() != null && !policy.getPolicyPlan().trim().isEmpty()
                ? policy.getPolicyPlan()
                : DEFAULT_PLAN;
        return plan + " for Device #" + policy.getSerialNumber()
                + "\n Plan Reference - " + policy.getPolicyNumber();
    }
}