package com.ruoyi.inventory.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ruoyi.common.exception.UtilException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.inventory.domain.HealthcareDrugArchive;
import com.ruoyi.inventory.domain.HealthcareDrugFiling;
import com.ruoyi.inventory.domain.HealthcareInventoryDrugout;
import com.ruoyi.inventory.domain.HealthcareInventoryDrugoutDetails;
import com.ruoyi.inventory.domain.HealthcareInventoryDrugoutType;
import com.ruoyi.inventory.domain.HealthcareInventoryStoreroom;
import com.ruoyi.inventory.mapper.HealthcareInventoryDrugoutMapper;
import com.ruoyi.inventory.service.IHealthcareDrugArchiveService;
import com.ruoyi.inventory.service.IHealthcareDrugFilingService;
import com.ruoyi.inventory.service.IHealthcareInventoryDrugoutService;
import com.ruoyi.inventory.service.IHealthcareInventoryDrugoutTypeService;
import com.ruoyi.inventory.service.IHealthcareInventoryStoreroomService;

/**
 * 药品出库记录 Service 业务处理层
 *
 * @author 钂嬫澗
 * @date 2024-10-07
 */
@Service
public class HealthcareInventoryDrugoutServiceImpl implements IHealthcareInventoryDrugoutService {
    private static final String UNIT_TYPE_BOX = "BOX";
    private static final String UNIT_TYPE_PACK = "PACK";

    @Autowired
    private HealthcareInventoryDrugoutMapper healthcareInventoryDrugoutMapper;

    @Autowired
    private IHealthcareInventoryDrugoutTypeService healthcareInventoryDrugoutTypeService;

    @Autowired
    private IHealthcareDrugArchiveService healthcareDrugArchiveService;

    @Autowired
    private IHealthcareDrugFilingService healthcareDrugFilingService;
    @Autowired
    private IHealthcareInventoryStoreroomService healthcareInventoryStoreroomService;

    /**
     * 查询药品出库记录
     *
     * @param id 药品出库记录主键
     * @return 药品出库记录
     */
    @Override
    public HealthcareInventoryDrugout selectHealthcareInventoryDrugoutById(Long id) {
        // 获取出库记录信息
        HealthcareInventoryDrugout drugOut = healthcareInventoryDrugoutMapper.selectHealthcareInventoryDrugoutById(id);

        if (drugOut != null) {
            // 查询出库记录信息后，使用其 id 查询对应的出库类型，并将结果回填到 drugOut 统一返回
            HealthcareInventoryDrugoutType outType = healthcareInventoryDrugoutTypeService
                    .selectHealthcareInventoryDrugoutTypeByOutTypeDrugOutId(drugOut.getId());

            if (outType != null) {
                // 若为调拨出库，需判断出库地点与入库地点是否一致，若一致则抛出异常
                drugOut.setInboundLocation(outType.getInboundLocation());
                drugOut.setSignee(outType.getSignee());
                drugOut.setProofMaterial(outType.getProofMaterial());
                drugOut.setPurposeDetails(outType.getPurposeDetails());
                drugOut.setUnit(outType.getUnit());
                drugOut.setExpirationDate(outType.getExpirationDate());
                drugOut.setCurrentDatetime(outType.getCurrentDatetime());
                drugOut.setDestroyer(outType.getDestroyer());
                drugOut.setDestructionLocation(outType.getDestructionLocation());
                drugOut.setDestructionProcess(outType.getDestructionProcess());
                drugOut.setDamageReason(outType.getDamageReason());
                drugOut.setDisposalMethod(outType.getDisposalMethod());
            }

            // 获取出库记录的药品档案信息
            List<HealthcareInventoryDrugoutDetails> details = drugOut.getHealthcareInventoryDrugoutDetailsList();

            if (!details.isEmpty()) {
                details.forEach(item -> {
                    HealthcareDrugArchive archive = healthcareDrugArchiveService
                            .selectHealthcareDrugArchiveById(item.getDrugId());
                    if (archive != null) {
                        item.setDrugId(archive.getId());
                        item.setMedicineName(archive.getMedicineName());
                        item.setBarcode(archive.getBarcode());
                        item.setManufacturer(archive.getManufacturer());
                    }
                    HealthcareInventoryStoreroom storeroom = healthcareInventoryStoreroomService
                            .selectHealthcareInventoryStoreroomById(item.getOutPointId());
                    if (storeroom != null) {
                        item.setOutPointName(storeroom.getStoreroomName());
                    }
                    if (item.getFilingId() != null) {
                        HealthcareDrugFiling filingRecord = healthcareDrugFilingService
                                .selectHealthcareDrugFilingById(item.getFilingId());
                        if (filingRecord != null) {
                            item.setRetailPrice(filingRecord.getRetailPrice());
                            item.setRemainingQuantity(filingRecord.getBoxCount());
                            item.setRemainingPackQuantity(filingRecord.getPackCount());
                            item.setInventoryUnit(filingRecord.getInventoryUnit());
                            item.setSplitUnit(filingRecord.getSplitUnit());
                            if (item.getUnitQuantity() == null) {
                                double minNumber = filingRecord.getMinNumber();
                                if (minNumber > 0) {
                                    item.setUnitQuantity((int) Math.round(minNumber));
                                } else {
                                    item.setUnitQuantity(1);
                                }
                            }
                        }
                    }
                    if (StringUtils.isBlank(item.getUnitType())) {
                        item.setUnitType(UNIT_TYPE_BOX);
                    }
                });
            }
        }

        return drugOut;
    }

    /**
     * 查询药品出库记录列表
     *
     * @param healthcareInventoryDrugout 药品出库记录
     * @return 药品出库记录列表
     */
    @Override
    public List<HealthcareInventoryDrugout> selectHealthcareInventoryDrugoutList(
            HealthcareInventoryDrugout healthcareInventoryDrugout) {
        List<HealthcareInventoryDrugout> list = healthcareInventoryDrugoutMapper
                .selectHealthcareInventoryDrugoutList(healthcareInventoryDrugout);
        list.forEach(item -> {
            HealthcareInventoryStoreroom storeroom = healthcareInventoryStoreroomService
                    .selectHealthcareInventoryStoreroomById(item.getOutPoint());
            item.setOutPointName(storeroom.getStoreroomName());
        });
        return list;
    }

    // 定义一个方法用于生成出库记录单号
    private String generateOrderNo() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); // 获取当前时间年月日时分秒
        String currentDataTime = simpleDateFormat.format(new Date());
        Random rd = new Random();
        int rdNumber = rd.nextInt(9000) + 1000; // 获取四位随机数
        return currentDataTime + rdNumber;
    }

    ;

    /**
     * 新增药品出库记录
     *
     * @param healthcareInventoryDrugout 药品出库记录
     * @return 结果
     */

    @Transactional
    @Override
    public int insertHealthcareInventoryDrugout(HealthcareInventoryDrugout healthcareInventoryDrugout) {
        List<HealthcareInventoryDrugoutDetails> details = healthcareInventoryDrugout
                .getHealthcareInventoryDrugoutDetailsList();
        if (details == null) {
            details = new ArrayList<>();
            healthcareInventoryDrugout.setHealthcareInventoryDrugoutDetailsList(details);
        }

        aggregateTotals(healthcareInventoryDrugout, details);

        if (healthcareInventoryDrugout.getOutType() == 0) {
            handleTransferInventory(healthcareInventoryDrugout, details);
        } else {
            validateDuplicateBatch(details);
            handleNormalInventory(details);
        }

        healthcareInventoryDrugout.setCreateTime(DateUtils.getNowDate());
        healthcareInventoryDrugout.setOutStatus(0);
        String orderNo = generateOrderNo();
        healthcareInventoryDrugout.setOutCode(orderNo);
        String currentUser = SecurityUtils.getUsername();
        healthcareInventoryDrugout.setOutPerson(currentUser);

        int rows = healthcareInventoryDrugoutMapper.insertHealthcareInventoryDrugout(healthcareInventoryDrugout);
        insertHealthcareInventoryDrugoutDetails(healthcareInventoryDrugout);

        HealthcareInventoryDrugoutType outType = new HealthcareInventoryDrugoutType();
        outType.setDrugOutId(healthcareInventoryDrugout.getId());
        outType.setInboundLocation(healthcareInventoryDrugout.getInboundLocation());
        outType.setSignee(healthcareInventoryDrugout.getSignee());
        outType.setProofMaterial(healthcareInventoryDrugout.getProofMaterial());
        outType.setPurposeDetails(healthcareInventoryDrugout.getPurposeDetails());
        outType.setUnit(healthcareInventoryDrugout.getUnit());
        outType.setExpirationDate(healthcareInventoryDrugout.getExpirationDate());
        outType.setCurrentDatetime(healthcareInventoryDrugout.getCurrentDatetime());
        outType.setDestroyer(healthcareInventoryDrugout.getDestroyer());
        outType.setDestructionLocation(healthcareInventoryDrugout.getDestructionLocation());
        outType.setDestructionProcess(healthcareInventoryDrugout.getDestructionProcess());
        outType.setDisposalMethod(healthcareInventoryDrugout.getDisposalMethod());
        outType.setDamageReason(healthcareInventoryDrugout.getDamageReason());

        healthcareInventoryDrugoutTypeService.insertHealthcareInventoryDrugoutType(outType);

        return rows;
    }

    /**
     * 修改药品出库记录
     *
     * @param healthcareInventoryDrugout 药品出库记录
     * @return 结果
     */
    @Transactional
    @Override
    public int updateHealthcareInventoryDrugout(HealthcareInventoryDrugout healthcareInventoryDrugout) {
        List<HealthcareInventoryDrugoutDetails> details = healthcareInventoryDrugout
                .getHealthcareInventoryDrugoutDetailsList();
        if (details == null) {
            details = new ArrayList<>();
            healthcareInventoryDrugout.setHealthcareInventoryDrugoutDetailsList(details);
        }

        aggregateTotals(healthcareInventoryDrugout, details);

        if (healthcareInventoryDrugout.getOutType() == 0) {
            handleTransferInventory(healthcareInventoryDrugout, details);
        } else {
            validateDuplicateBatch(details);
            handleNormalInventory(details);
        }

        healthcareInventoryDrugout.setUpdateTime(DateUtils.getNowDate());
        healthcareInventoryDrugout.setOutStatus(0);
        String orderNo = generateOrderNo();
        healthcareInventoryDrugout.setOutCode(orderNo);
        String currentUser = SecurityUtils.getUsername();
        healthcareInventoryDrugout.setOutPerson(currentUser);

        int rows = healthcareInventoryDrugoutMapper.updateHealthcareInventoryDrugout(healthcareInventoryDrugout);

        healthcareInventoryDrugoutMapper
                .deleteHealthcareInventoryDrugoutDetailsByDrugOutId(healthcareInventoryDrugout.getId());
        insertHealthcareInventoryDrugoutDetails(healthcareInventoryDrugout);

        HealthcareInventoryDrugoutType outType = healthcareInventoryDrugoutTypeService
                .selectHealthcareInventoryDrugoutTypeByOutTypeDrugOutId(healthcareInventoryDrugout.getId());
        if (outType != null) {
            outType.setInboundLocation(healthcareInventoryDrugout.getInboundLocation());
            outType.setSignee(healthcareInventoryDrugout.getSignee());
            outType.setProofMaterial(healthcareInventoryDrugout.getProofMaterial());
            outType.setPurposeDetails(healthcareInventoryDrugout.getPurposeDetails());
            outType.setUnit(healthcareInventoryDrugout.getUnit());
            outType.setExpirationDate(healthcareInventoryDrugout.getExpirationDate());
            outType.setCurrentDatetime(healthcareInventoryDrugout.getCurrentDatetime());
            outType.setDestroyer(healthcareInventoryDrugout.getDestroyer());
            outType.setDestructionLocation(healthcareInventoryDrugout.getDestructionLocation());
            outType.setDestructionProcess(healthcareInventoryDrugout.getDestructionProcess());
            outType.setDisposalMethod(healthcareInventoryDrugout.getDisposalMethod());
            outType.setDamageReason(healthcareInventoryDrugout.getDamageReason());
            healthcareInventoryDrugoutTypeService.updateHealthcareInventoryDrugoutType(outType);
        } else {
            outType = new HealthcareInventoryDrugoutType();
            outType.setDrugOutId(healthcareInventoryDrugout.getId());
            outType.setInboundLocation(healthcareInventoryDrugout.getInboundLocation());
            outType.setSignee(healthcareInventoryDrugout.getSignee());
            outType.setProofMaterial(healthcareInventoryDrugout.getProofMaterial());
            outType.setPurposeDetails(healthcareInventoryDrugout.getPurposeDetails());
            outType.setUnit(healthcareInventoryDrugout.getUnit());
            outType.setExpirationDate(healthcareInventoryDrugout.getExpirationDate());
            outType.setCurrentDatetime(healthcareInventoryDrugout.getCurrentDatetime());
            outType.setDestroyer(healthcareInventoryDrugout.getDestroyer());
            outType.setDestructionLocation(healthcareInventoryDrugout.getDestructionLocation());
            outType.setDestructionProcess(healthcareInventoryDrugout.getDestructionProcess());
            outType.setDisposalMethod(healthcareInventoryDrugout.getDisposalMethod());
            outType.setDamageReason(healthcareInventoryDrugout.getDamageReason());
            healthcareInventoryDrugoutTypeService.insertHealthcareInventoryDrugoutType(outType);
        }

        return rows;
    }

    /**
     * 批量删除药品出库记录
     *
     * @param ids 需要删除的药品出库记录主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteHealthcareInventoryDrugoutByIds(Long[] ids) {
        healthcareInventoryDrugoutMapper.deleteHealthcareInventoryDrugoutDetailsByDrugOutIds(ids);
        return healthcareInventoryDrugoutMapper.deleteHealthcareInventoryDrugoutByIds(ids);
    }

    /**
     * 删除药品出库记录信息
     *
     * @param id 药品出库记录主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteHealthcareInventoryDrugoutById(Long id) {
        healthcareInventoryDrugoutMapper.deleteHealthcareInventoryDrugoutDetailsByDrugOutId(id);
        return healthcareInventoryDrugoutMapper.deleteHealthcareInventoryDrugoutById(id);
    }

    @Override
    public int saveHealthcareInventoryDrugout(HealthcareInventoryDrugout healthcareInventoryDrugout) {
        List<HealthcareInventoryDrugoutDetails> details = healthcareInventoryDrugout
                .getHealthcareInventoryDrugoutDetailsList();
        if (details == null) {
            details = new ArrayList<>();
            healthcareInventoryDrugout.setHealthcareInventoryDrugoutDetailsList(details);
        }

        aggregateTotals(healthcareInventoryDrugout, details);
        if (healthcareInventoryDrugout.getOutType() != 0) {
            validateDuplicateBatch(details);
        }

        if (healthcareInventoryDrugout.getId() == null) {
            healthcareInventoryDrugout.setCreateTime(DateUtils.getNowDate());
            healthcareInventoryDrugout.setOutStatus(1);
            String orNumber = generateOrderNo();
            healthcareInventoryDrugout.setOutCode(orNumber);
            String person = SecurityUtils.getUsername();
            healthcareInventoryDrugout.setOutPerson(person);

            int rows = healthcareInventoryDrugoutMapper.insertHealthcareInventoryDrugout(healthcareInventoryDrugout);
            insertHealthcareInventoryDrugoutDetails(healthcareInventoryDrugout);

            HealthcareInventoryDrugoutType outType = new HealthcareInventoryDrugoutType();
            outType.setDrugOutId(healthcareInventoryDrugout.getId());
            outType.setInboundLocation(healthcareInventoryDrugout.getInboundLocation());
            outType.setSignee(healthcareInventoryDrugout.getSignee());
            outType.setProofMaterial(healthcareInventoryDrugout.getProofMaterial());
            outType.setPurposeDetails(healthcareInventoryDrugout.getPurposeDetails());
            outType.setUnit(healthcareInventoryDrugout.getUnit());
            outType.setExpirationDate(healthcareInventoryDrugout.getExpirationDate());
            outType.setCurrentDatetime(healthcareInventoryDrugout.getCurrentDatetime());
            outType.setDestroyer(healthcareInventoryDrugout.getDestroyer());
            outType.setDestructionLocation(healthcareInventoryDrugout.getDestructionLocation());
            outType.setDestructionProcess(healthcareInventoryDrugout.getDestructionProcess());
            outType.setDisposalMethod(healthcareInventoryDrugout.getDisposalMethod());
            outType.setDamageReason(healthcareInventoryDrugout.getDamageReason());

            healthcareInventoryDrugoutTypeService.insertHealthcareInventoryDrugoutType(outType);
            return rows;
        } else {
            healthcareInventoryDrugoutMapper
                    .deleteHealthcareInventoryDrugoutDetailsByDrugOutId(healthcareInventoryDrugout.getId());
            insertHealthcareInventoryDrugoutDetails(healthcareInventoryDrugout);

            HealthcareInventoryDrugoutType outType = new HealthcareInventoryDrugoutType();
            outType.setDrugOutId(healthcareInventoryDrugout.getId());
            outType.setInboundLocation(healthcareInventoryDrugout.getInboundLocation());
            outType.setSignee(healthcareInventoryDrugout.getSignee());
            outType.setProofMaterial(healthcareInventoryDrugout.getProofMaterial());
            outType.setPurposeDetails(healthcareInventoryDrugout.getPurposeDetails());
            outType.setUnit(healthcareInventoryDrugout.getUnit());
            outType.setExpirationDate(healthcareInventoryDrugout.getExpirationDate());
            outType.setCurrentDatetime(healthcareInventoryDrugout.getCurrentDatetime());
            outType.setDestroyer(healthcareInventoryDrugout.getDestroyer());
            outType.setDestructionLocation(healthcareInventoryDrugout.getDestructionLocation());
            outType.setDestructionProcess(healthcareInventoryDrugout.getDestructionProcess());
            outType.setDisposalMethod(healthcareInventoryDrugout.getDisposalMethod());
            outType.setDamageReason(healthcareInventoryDrugout.getDamageReason());

            healthcareInventoryDrugoutTypeService.updateHealthcareInventoryDrugoutType(outType);
            return healthcareInventoryDrugoutMapper.updateHealthcareInventoryDrugout(healthcareInventoryDrugout);
        }
    }

    /**
     * 汇总出库总量，用于记录药品出库的详细信息
     *
     * @param healthcareInventoryDrugout 药品出库记录对象
     */
    private void aggregateTotals(HealthcareInventoryDrugout master, List<HealthcareInventoryDrugoutDetails> details) {
        int totalBoxes = 0;
        int totalPacks = 0;
        int totalMinUnits = 0;
        for (HealthcareInventoryDrugoutDetails detail : details) {
            String unitType = normalizeUnitType(detail);
            int quantity = extractQuantity(detail);
            int unitQuantity = extractUnitQuantity(detail);
            if (UNIT_TYPE_PACK.equals(unitType)) {
                totalPacks += quantity;
                totalMinUnits += quantity;
            } else {
                totalBoxes += quantity;
                totalMinUnits += quantity * unitQuantity;
            }
        }
        master.setOutBoxQuantity((long) totalBoxes);
        master.setOutPackQuantity((long) totalPacks);
        master.setOutQuantity((long) totalMinUnits);
    }

    private void validateDuplicateBatch(List<HealthcareInventoryDrugoutDetails> details) {
        Set<String> batchNumbers = new HashSet<>();
        for (HealthcareInventoryDrugoutDetails detail : details) {
            String batch = detail.getOutBatch();
            if (StringUtils.isNotEmpty(batch) && !batchNumbers.add(batch)) {
                throw new RuntimeException("批次号重复");
            }
        }
    }

    private void handleTransferInventory(HealthcareInventoryDrugout master,
            List<HealthcareInventoryDrugoutDetails> details) {
        if (master.getOutPoint() == null || master.getInboundLocation() == null) {
            throw new UtilException("出入库地点不能为空");
        }
        if (master.getOutPoint().equals(master.getInboundLocation())) {
            throw new RuntimeException("出库地点与入库地点不能相同");
        }
        for (HealthcareInventoryDrugoutDetails detail : details) {
            if (detail.getOutPointId() == null || !master.getOutPoint().equals(detail.getOutPointId())) {
                throw new RuntimeException("出库库房记录与药品库房记录不一致，请重新选择");
            }
            applyTransferInventory(master, detail);
        }
    }

    private void applyTransferInventory(HealthcareInventoryDrugout master, HealthcareInventoryDrugoutDetails detail) {
        HealthcareDrugFiling outLookup = new HealthcareDrugFiling();
        outLookup.setStoreroomId(master.getOutPoint());
        outLookup.setArchiveId(detail.getDrugId());
        outLookup.setBatch(detail.getOutBatch());

        HealthcareDrugFiling outInventory = healthcareDrugFilingService
                .selectHealthcareDrugFilingByIdAndStoreroom(outLookup);
        if (outInventory == null) {
            throw new UtilException("未找到出库地点对应的批次");
        }
        adjustInventoryForOut(outInventory, detail);
        healthcareDrugFilingService.updateHealthcareDrugFiling(outInventory);

        HealthcareDrugFiling inLookup = new HealthcareDrugFiling();
        inLookup.setStoreroomId(master.getInboundLocation());
        inLookup.setArchiveId(detail.getDrugId());
        inLookup.setBatch(detail.getOutBatch());

        HealthcareDrugFiling inInventory = healthcareDrugFilingService
                .selectHealthcareDrugFilingByIdAndStoreroom(inLookup);
        if (inInventory != null) {
            adjustInventoryForIn(inInventory, detail);
            healthcareDrugFilingService.updateHealthcareDrugFiling(inInventory);
        } else {
            initializeInventoryForNewRecord(inLookup, detail);
            healthcareDrugFilingService.insertHealthcareDrugFiling(inLookup);
        }
    }

    private void handleNormalInventory(List<HealthcareInventoryDrugoutDetails> details) {
        for (HealthcareInventoryDrugoutDetails detail : details) {
            if (detail.getFilingId() == null) {
                throw new UtilException("库存记录缺失");
            }
            HealthcareDrugFiling filing = healthcareDrugFilingService
                    .selectHealthcareDrugFilingById(detail.getFilingId());
            if (filing == null) {
                throw new UtilException("未找到对应的库存记录");
            }
            adjustInventoryForOut(filing, detail);
            healthcareDrugFilingService.updateHealthcareDrugFiling(filing);
        }
    }

    private void adjustInventoryForOut(HealthcareDrugFiling filing, HealthcareInventoryDrugoutDetails detail) {
        String unitType = normalizeUnitType(detail);
        int quantity = extractQuantity(detail);
        if (quantity <= 0) {
            return;
        }
        if (UNIT_TYPE_PACK.equals(unitType)) {
            int current = filing.getPackCount() == null ? 0 : filing.getPackCount();
            if (quantity > current) {
                throw new UtilException((detail.getOutBatch() == null ? "" : detail.getOutBatch()) + "批次拆零数量不足");
            }
            filing.setPackCount(current - quantity);
        } else {
            int current = filing.getBoxCount() == null ? 0 : filing.getBoxCount();
            if (quantity > current) {
                throw new UtilException((detail.getOutBatch() == null ? "" : detail.getOutBatch()) + "批次库存数量不足");
            }
            filing.setBoxCount(current - quantity);
        }
    }

    private void adjustInventoryForIn(HealthcareDrugFiling filing, HealthcareInventoryDrugoutDetails detail) {
        String unitType = normalizeUnitType(detail);
        int quantity = extractQuantity(detail);
        if (quantity <= 0) {
            return;
        }
        if (UNIT_TYPE_PACK.equals(unitType)) {
            int current = filing.getPackCount() == null ? 0 : filing.getPackCount();
            filing.setPackCount(current + quantity);
        } else {
            int current = filing.getBoxCount() == null ? 0 : filing.getBoxCount();
            filing.setBoxCount(current + quantity);
        }
    }

    private void initializeInventoryForNewRecord(HealthcareDrugFiling filing,
            HealthcareInventoryDrugoutDetails detail) {
        filing.setExpiryDate(detail.getExpiryDate());
        filing.setRetailPrice(detail.getRetailPrice());
        filing.setBoxCount(0);
        filing.setPackCount(0);
        // 计算并补充最小单位价格与数量（用于新库区首次建立批次记录）
        try {
            HealthcareDrugArchive archive = healthcareDrugArchiveService
                    .selectHealthcareDrugArchiveById(detail.getDrugId());
            if (archive != null) {
                String mnStr = archive.getMinNumber();
                double minNumber = 0d;
                if (org.apache.commons.lang3.StringUtils.isNotBlank(mnStr)) {
                    try {
                        minNumber = Double.parseDouble(mnStr);
                    } catch (Exception e) {
                    }
                }
                filing.setMinNumber(minNumber);
                if ("Y".equalsIgnoreCase(archive.getIsSplit()) && minNumber > 0) {
                    java.math.BigDecimal retail = new java.math.BigDecimal(String.valueOf(detail.getRetailPrice()));
                    java.math.BigDecimal mn = new java.math.BigDecimal(String.valueOf(minNumber));
                    java.math.BigDecimal minPrice = retail.divide(mn, 2, java.math.RoundingMode.CEILING);
                    filing.setMinPrice(minPrice.doubleValue());
                } else {
                    filing.setMinPrice(detail.getRetailPrice());
                }
                if (archive.getPackageUnit() != null) {
                    filing.setInventoryUnit(archive.getPackageUnit());
                }
                if (archive.getSplitUnit() != null) {
                    filing.setSplitUnit(archive.getSplitUnit());
                }
            }
        } catch (Exception ignore) {
        }
        String unitType = normalizeUnitType(detail);
        int quantity = extractQuantity(detail);
        if (UNIT_TYPE_PACK.equals(unitType)) {
            filing.setPackCount(quantity);
        } else {
            filing.setBoxCount(quantity);
        }
    }

    private String normalizeUnitType(HealthcareInventoryDrugoutDetails detail) {
        String unitType = detail.getUnitType();
        if (StringUtils.isBlank(unitType)) {
            unitType = UNIT_TYPE_BOX;
        } else {
            unitType = unitType.toUpperCase();
            if (!UNIT_TYPE_PACK.equals(unitType)) {
                unitType = UNIT_TYPE_BOX;
            }
        }
        detail.setUnitType(unitType);
        return unitType;
    }

    private int extractQuantity(HealthcareInventoryDrugoutDetails detail) {
        Integer quantity = detail.getQuantity();
        if (quantity == null || quantity < 0) {
            quantity = 0;
        }
        detail.setQuantity(quantity);
        return quantity;
    }

    private int extractUnitQuantity(HealthcareInventoryDrugoutDetails detail) {
        Integer unitQuantity = detail.getUnitQuantity();
        if (unitQuantity == null || unitQuantity <= 0) {
            unitQuantity = 1;
            detail.setUnitQuantity(unitQuantity);
        }
        return unitQuantity;
    }

    public void insertHealthcareInventoryDrugoutDetails(HealthcareInventoryDrugout healthcareInventoryDrugout) {
        List<HealthcareInventoryDrugoutDetails> healthcareInventoryDrugoutDetailsList = healthcareInventoryDrugout
                .getHealthcareInventoryDrugoutDetailsList();
        Long id = healthcareInventoryDrugout.getId();
        if (StringUtils.isNotNull(healthcareInventoryDrugoutDetailsList)) {
            List<HealthcareInventoryDrugoutDetails> list = new ArrayList<HealthcareInventoryDrugoutDetails>();
            for (HealthcareInventoryDrugoutDetails healthcareInventoryDrugoutDetails : healthcareInventoryDrugoutDetailsList) {
                healthcareInventoryDrugoutDetails.setDrugOutId(id);
                list.add(healthcareInventoryDrugoutDetails);
            }
            if (list.size() > 0) {
                healthcareInventoryDrugoutMapper.batchHealthcareInventoryDrugoutDetails(list);
            }
        }
    }
}
