|  | @@ -0,0 +1,305 @@
 | 
	
		
			
				|  |  | +package com.ruoyi.ccb.service.impl;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import cn.hutool.core.util.ObjectUtil;
 | 
	
		
			
				|  |  | +import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  | +import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  | +import com.github.pagehelper.PageInfo;
 | 
	
		
			
				|  |  | +import com.ruoyi.ccb.domain.*;
 | 
	
		
			
				|  |  | +import com.ruoyi.ccb.domain.basic.CargoDetail;
 | 
	
		
			
				|  |  | +import com.ruoyi.ccb.domain.basic.CargoLockInfo;
 | 
	
		
			
				|  |  | +import com.ruoyi.ccb.domain.basic.Page;
 | 
	
		
			
				|  |  | +import com.ruoyi.ccb.domain.basic.SyncedOrg;
 | 
	
		
			
				|  |  | +import com.ruoyi.ccb.service.CcbHttpService;
 | 
	
		
			
				|  |  | +import com.ruoyi.common.core.domain.AjaxResult;
 | 
	
		
			
				|  |  | +import com.ruoyi.warehouseBusiness.domain.TWarehousebillsitems;
 | 
	
		
			
				|  |  | +import com.ruoyi.warehouseBusiness.service.IWarehouseBillsCcbService;
 | 
	
		
			
				|  |  | +import lombok.AllArgsConstructor;
 | 
	
		
			
				|  |  | +import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  | +import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import java.math.BigDecimal;
 | 
	
		
			
				|  |  | +import java.util.ArrayList;
 | 
	
		
			
				|  |  | +import java.util.List;
 | 
	
		
			
				|  |  | +import java.util.Map;
 | 
	
		
			
				|  |  | +import java.util.stream.Collectors;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * CCB-HTTP接口实现
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * @author s
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +@Service
 | 
	
		
			
				|  |  | +@AllArgsConstructor
 | 
	
		
			
				|  |  | +public class CcbHttpServiceImpl implements CcbHttpService {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private final IWarehouseBillsCcbService ccbService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public VoucherR takeVoucherIsExist(Voucher voucher) {
 | 
	
		
			
				|  |  | +        // 库存帐查询
 | 
	
		
			
				|  |  | +        List<Map<String, Object>> stockList = ccbService.getStockList(voucher.getTakeVoucher(), voucher.getUserName());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        VoucherR voucherR = new VoucherR();
 | 
	
		
			
				|  |  | +        if (stockList.size() > 0) {
 | 
	
		
			
				|  |  | +            voucherR.setIsExist("Y");
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            voucherR.setIsExist("N");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        voucherR.setBeLongUser(voucher.getUserName());
 | 
	
		
			
				|  |  | +        voucherR.setUscc(voucher.getUscc());
 | 
	
		
			
				|  |  | +        return voucherR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public VoucherDetailR takeVoucherDetail(Voucher voucher) {
 | 
	
		
			
				|  |  | +        // 库存帐查询
 | 
	
		
			
				|  |  | +        List<CargoDetail> cargos = new ArrayList<>();
 | 
	
		
			
				|  |  | +        List<Map<String, Object>> stockList = ccbService.getStockList(voucher.getTakeVoucher(), voucher.getUserName());
 | 
	
		
			
				|  |  | +        stockList.forEach(map -> {
 | 
	
		
			
				|  |  | +            String temp = JSON.toJSONString(map);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            CargoDetail detail = JSON.parseObject(temp, CargoDetail.class);
 | 
	
		
			
				|  |  | +            detail.setNumberUnit("件");
 | 
	
		
			
				|  |  | +            detail.setWeightUnit("千克");
 | 
	
		
			
				|  |  | +            detail.setCargoBelong(voucher.getUserName());
 | 
	
		
			
				|  |  | +            detail.setInStorageNumber(detail.getTakeVoucher());
 | 
	
		
			
				|  |  | +            detail.setRemainNumber(detail.getNumberLeft());
 | 
	
		
			
				|  |  | +            detail.setRemainWeight(detail.getWeightLeft());
 | 
	
		
			
				|  |  | +            detail.setElectronicTags(ccbService.getLabel(detail.getTakeVoucher()));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            JSONObject object = JSON.parseObject(temp);
 | 
	
		
			
				|  |  | +            if (!"0".equals(object.getString("lockStatus"))) {
 | 
	
		
			
				|  |  | +                CargoLockInfo lockInfo = new CargoLockInfo();
 | 
	
		
			
				|  |  | +                lockInfo.setCargoNo(detail.getCargoNo());
 | 
	
		
			
				|  |  | +                lockInfo.setBlNumber(detail.getBlNumber());
 | 
	
		
			
				|  |  | +                lockInfo.setCargoBelong(detail.getCargoBelong());
 | 
	
		
			
				|  |  | +                lockInfo.setTakeVoucher(detail.getTakeVoucher());
 | 
	
		
			
				|  |  | +                lockInfo.setNumber(detail.getNumberLeft());
 | 
	
		
			
				|  |  | +                lockInfo.setNumberUnit(detail.getNumberUnit());
 | 
	
		
			
				|  |  | +                lockInfo.setWeight(detail.getWeightLeft());
 | 
	
		
			
				|  |  | +                lockInfo.setWeightUnit(detail.getWeightUnit());
 | 
	
		
			
				|  |  | +                lockInfo.setSpeci(detail.getSpeci());
 | 
	
		
			
				|  |  | +                lockInfo.setReasonCode("PLGL");
 | 
	
		
			
				|  |  | +                lockInfo.setLockTime(object.getDate("lockTime"));
 | 
	
		
			
				|  |  | +                lockInfo.setWrNumber(detail.getWrNumber());
 | 
	
		
			
				|  |  | +                lockInfo.setElectronicTags(detail.getElectronicTags());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        VoucherDetailR detailR = new VoucherDetailR();
 | 
	
		
			
				|  |  | +        detailR.setTakeVoucher(voucher.getTakeVoucher());
 | 
	
		
			
				|  |  | +        detailR.setStorageEnterpriseName(voucher.getUserName());
 | 
	
		
			
				|  |  | +        detailR.setBondedStatus(0);
 | 
	
		
			
				|  |  | +        detailR.setUserName(voucher.getUserName());
 | 
	
		
			
				|  |  | +        detailR.setUscc(voucher.getUscc());
 | 
	
		
			
				|  |  | +        detailR.setCargos(cargos);
 | 
	
		
			
				|  |  | +        return detailR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public PledgeR cargoPledge(Pledge pledge) {
 | 
	
		
			
				|  |  | +        List<String> billNoList = pledge.getCargos()
 | 
	
		
			
				|  |  | +                .stream()
 | 
	
		
			
				|  |  | +                .map(CargoDetail::getTakeVoucher)
 | 
	
		
			
				|  |  | +                .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 出质处理
 | 
	
		
			
				|  |  | +        AjaxResult result = ccbService.lockStock(pledge.getNewUserName(), billNoList, false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        PledgeR pledgeR = new PledgeR();
 | 
	
		
			
				|  |  | +        pledgeR.setUserName(pledge.getUserName());
 | 
	
		
			
				|  |  | +        pledgeR.setUscc(pledge.getUscc());
 | 
	
		
			
				|  |  | +        pledgeR.setNewUserName(pledge.getNewUserName());
 | 
	
		
			
				|  |  | +        pledgeR.setNewUserNameUscc(pledge.getNewUserNameUscc());
 | 
	
		
			
				|  |  | +        pledgeR.setCargos(pledge.getCargos());
 | 
	
		
			
				|  |  | +        if ((int) result.get("code") != 200) {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("N");
 | 
	
		
			
				|  |  | +            pledgeR.setReason((String) result.get("msg"));
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("Y");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return pledgeR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public PledgeR cargoPledgeOut(Pledge pledge) {
 | 
	
		
			
				|  |  | +        List<String> billNoList = pledge.getCargos()
 | 
	
		
			
				|  |  | +                .stream()
 | 
	
		
			
				|  |  | +                .map(CargoDetail::getTakeVoucher)
 | 
	
		
			
				|  |  | +                .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 解质处理
 | 
	
		
			
				|  |  | +        AjaxResult result = ccbService.unlockStock(billNoList, false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        PledgeR pledgeR = new PledgeR();
 | 
	
		
			
				|  |  | +        pledgeR.setUserName(pledge.getNewUserName());
 | 
	
		
			
				|  |  | +        pledgeR.setUscc(pledge.getNewUserNameUscc());
 | 
	
		
			
				|  |  | +        pledgeR.setCargos(pledge.getCargos());
 | 
	
		
			
				|  |  | +        if ((int) result.get("code") != 200) {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("N");
 | 
	
		
			
				|  |  | +            pledgeR.setReason((String) result.get("msg"));
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("Y");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return pledgeR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | +    public InOutCargoR inCargoReq(InOutCargo inOutCargo) {
 | 
	
		
			
				|  |  | +        List<TWarehousebillsitems> items = convert(inOutCargo.getCargos());
 | 
	
		
			
				|  |  | +        AjaxResult result = ccbService.inAndOutStock("SJRK", items);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        InOutCargoR inOutCargoR = new InOutCargoR();
 | 
	
		
			
				|  |  | +        inOutCargoR.setUserName(inOutCargo.getUserName());
 | 
	
		
			
				|  |  | +        inOutCargoR.setUscc(inOutCargo.getUscc());
 | 
	
		
			
				|  |  | +        inOutCargoR.setReqUser(inOutCargo.getReqUser());
 | 
	
		
			
				|  |  | +        if ((int) result.get("code") != 200) {
 | 
	
		
			
				|  |  | +            inOutCargoR.setResult("N");
 | 
	
		
			
				|  |  | +            inOutCargoR.setReason((String) result.get("msg"));
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            inOutCargoR.setResult("Y");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return inOutCargoR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public InOutCargoR outCargoReq(InOutCargo inOutCargo) {
 | 
	
		
			
				|  |  | +        List<TWarehousebillsitems> items = convert(inOutCargo.getCargos());
 | 
	
		
			
				|  |  | +        AjaxResult result = ccbService.inAndOutStock("SJCK", items);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        InOutCargoR inOutCargoR = new InOutCargoR();
 | 
	
		
			
				|  |  | +        inOutCargoR.setUserName(inOutCargo.getUserName());
 | 
	
		
			
				|  |  | +        inOutCargoR.setUscc(inOutCargo.getUscc());
 | 
	
		
			
				|  |  | +        inOutCargoR.setReqUser(inOutCargo.getReqUser());
 | 
	
		
			
				|  |  | +        if ((int) result.get("code") != 200) {
 | 
	
		
			
				|  |  | +            inOutCargoR.setResult("N");
 | 
	
		
			
				|  |  | +            inOutCargoR.setReason((String) result.get("msg"));
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            inOutCargoR.setResult("Y");
 | 
	
		
			
				|  |  | +            inOutCargoR.setReason("");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return inOutCargoR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public Page syncOrg(SyncOrg syncOrg) {
 | 
	
		
			
				|  |  | +        Page page = syncOrg.getPage();
 | 
	
		
			
				|  |  | +        if (ObjectUtil.isNull(page)) {
 | 
	
		
			
				|  |  | +            page = new Page();
 | 
	
		
			
				|  |  | +            page.setPageNo(1);
 | 
	
		
			
				|  |  | +            page.setPageSize(10);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<Map<String, Object>> orgList = ccbService.getSyncOrg(page.getPageNo(), page.getPageSize(), syncOrg.getRegisterAfter());
 | 
	
		
			
				|  |  | +        page.setTotalRecords(new PageInfo<>(orgList).getTotal());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<SyncedOrg> orgListR = orgList.stream()
 | 
	
		
			
				|  |  | +                .map(e -> JSON.parseObject(JSON.toJSONString(e), SyncedOrg.class))
 | 
	
		
			
				|  |  | +                .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        page.setContent(orgListR);
 | 
	
		
			
				|  |  | +        return page;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public PledgeR generateWrNumber(Pledge pledge) {
 | 
	
		
			
				|  |  | +        List<CargoDetail> cargos = pledge.getCargos();
 | 
	
		
			
				|  |  | +        List<String> billNoList = cargos.stream()
 | 
	
		
			
				|  |  | +                .map(CargoDetail::getTakeVoucher)
 | 
	
		
			
				|  |  | +                .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        AjaxResult result = ccbService.unlockStock(billNoList, true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        PledgeR pledgeR = new PledgeR();
 | 
	
		
			
				|  |  | +        pledgeR.setUserName(pledge.getUserName());
 | 
	
		
			
				|  |  | +        pledgeR.setUscc(pledge.getUscc());
 | 
	
		
			
				|  |  | +        pledgeR.setNewUserName(pledge.getNewUserName());
 | 
	
		
			
				|  |  | +        pledgeR.setNewUserNameUscc(pledge.getNewUserNameUscc());
 | 
	
		
			
				|  |  | +        if ((int) result.get("code") != 200) {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("N");
 | 
	
		
			
				|  |  | +            pledgeR.setReason((String) result.get("msg"));
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("Y");
 | 
	
		
			
				|  |  | +            cargos.forEach(cargo -> cargo.setWrNumber(cargo.getTakeVoucher()));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pledgeR.setCargos(cargos);
 | 
	
		
			
				|  |  | +        return pledgeR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public PledgeR cancelWrNumber(Pledge pledge) {
 | 
	
		
			
				|  |  | +        List<String> billNoList = pledge.getCargos()
 | 
	
		
			
				|  |  | +                .stream()
 | 
	
		
			
				|  |  | +                .map(CargoDetail::getTakeVoucher)
 | 
	
		
			
				|  |  | +                .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 解质处理
 | 
	
		
			
				|  |  | +        AjaxResult result = ccbService.unlockStock(billNoList, true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        PledgeR pledgeR = new PledgeR();
 | 
	
		
			
				|  |  | +        pledgeR.setUserName(pledge.getUserName());
 | 
	
		
			
				|  |  | +        pledgeR.setUscc(pledge.getUscc());
 | 
	
		
			
				|  |  | +        pledgeR.setNewUserName(pledge.getNewUserName());
 | 
	
		
			
				|  |  | +        pledgeR.setNewUserNameUscc(pledge.getNewUserNameUscc());
 | 
	
		
			
				|  |  | +        if ((int) result.get("code") != 200) {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("N");
 | 
	
		
			
				|  |  | +            pledgeR.setReason((String) result.get("msg"));
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            pledgeR.setResult("Y");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pledgeR.setCargos(pledge.getCargos());
 | 
	
		
			
				|  |  | +        return pledgeR;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 数据转换
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param cargos 出入库数据
 | 
	
		
			
				|  |  | +     * @return 结果
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private List<TWarehousebillsitems> convert(List<CargoDetail> cargos) {
 | 
	
		
			
				|  |  | +        List<TWarehousebillsitems> items = new ArrayList<>();
 | 
	
		
			
				|  |  | +        for (CargoDetail cargo : cargos) {
 | 
	
		
			
				|  |  | +            TWarehousebillsitems item = new TWarehousebillsitems();
 | 
	
		
			
				|  |  | +            item.setCargoNo(cargo.getCargoNo());
 | 
	
		
			
				|  |  | +            item.setCargoBelong(cargo.getCargoBelong());
 | 
	
		
			
				|  |  | +            item.setfMblno(cargo.getBlNumber());
 | 
	
		
			
				|  |  | +            item.setfPackagespecs(cargo.getSpeci());
 | 
	
		
			
				|  |  | +            item.setfOriginalbillno(cargo.getBlNumber());
 | 
	
		
			
				|  |  | +            item.setfBillingway(3L);
 | 
	
		
			
				|  |  | +            item.setfCntqty(1L);
 | 
	
		
			
				|  |  | +            item.setWarehouseNo(cargo.getWarehouseNo());
 | 
	
		
			
				|  |  | +            item.setShelvesNo(cargo.getShelvesName());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (ObjectUtil.isNotNull(cargo.getNumber())) {
 | 
	
		
			
				|  |  | +                item.setfPlanqty(cargo.getNumber());
 | 
	
		
			
				|  |  | +                item.setfQty(cargo.getNumber());
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                String[] s = String.valueOf(cargo.getWeight()).split("\\.");
 | 
	
		
			
				|  |  | +                item.setfPlanqty(Long.parseLong(s[0]));
 | 
	
		
			
				|  |  | +                item.setfQty(Long.parseLong(s[0]));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (ObjectUtil.isNotNull(cargo.getWeight())) {
 | 
	
		
			
				|  |  | +                item.setfPlangrossweight(BigDecimal.valueOf(cargo.getWeight()));
 | 
	
		
			
				|  |  | +                item.setfPlannetweight(BigDecimal.valueOf(cargo.getWeight()));
 | 
	
		
			
				|  |  | +                item.setfGrossweight(BigDecimal.valueOf(cargo.getWeight()));
 | 
	
		
			
				|  |  | +                item.setfNetweight(BigDecimal.valueOf(cargo.getWeight()));
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                item.setfPlangrossweight(BigDecimal.valueOf(cargo.getNumber()));
 | 
	
		
			
				|  |  | +                item.setfPlannetweight(BigDecimal.valueOf(cargo.getNumber()));
 | 
	
		
			
				|  |  | +                item.setfGrossweight(BigDecimal.valueOf(cargo.getNumber()));
 | 
	
		
			
				|  |  | +                item.setfNetweight(BigDecimal.valueOf(cargo.getNumber()));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // fSealno代替保税字段
 | 
	
		
			
				|  |  | +            item.setfSealno(cargo.getBondedStatus());
 | 
	
		
			
				|  |  | +            item.setfPlanvolumn(BigDecimal.ZERO);
 | 
	
		
			
				|  |  | +            item.setfVolumn(BigDecimal.ZERO);
 | 
	
		
			
				|  |  | +            item.setfBillstatus(10L);
 | 
	
		
			
				|  |  | +            item.setElectronicTags(cargo.getElectronicTags());
 | 
	
		
			
				|  |  | +            items.add(item);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return items;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |