Commit d22db446 by HlQ

[add] 添加收款记录管理和发票管理

[chg] 代码优化、bug修改
1 parent 8ef39f9c
Showing 57 changed files with 1021 additions and 235 deletions
......@@ -64,19 +64,17 @@ public class ResBodyAdvice implements ResponseBodyAdvice<Object> {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResultVO methodArgExceptionHandler(Exception e) {
log.error("方法参数异常", e);
return ResultUtil.error("Method parameter error.");
return ResultUtil.error("方法参数异常");
}
@ExceptionHandler(NotLoginException.class)
public ResultVO notLoginExceptionHandler(Exception e) {
log.error("未登录", e.getMessage());
return ResultUtil.error(401, "请重新登录");
}
@ExceptionHandler(NotPermissionException.class)
public ResultVO notPermissionExceptionHandler(NotPermissionException e) {
log.error("无权限:{}", e.getPermission());
return ResultUtil.error(500, "您没有该功能使用权限!");
return ResultUtil.error(512, "您没有该功能使用权限!");
}
}
......@@ -27,7 +27,7 @@ public class AccountController {
@GetMapping("/account")
@SaCheckPermission(value = "account:query", orRole = "admin")
public Account getProductByID(Integer id) {
public Account getProductById(Integer id) {
return accountService.getById(id);
}
......
......@@ -6,7 +6,6 @@ import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vion.cron.ContractRunner;
......@@ -31,7 +30,6 @@ public class ContractController {
private final IContractService contractService;
private final ContractRunner contractRunner;
private final IRContractStoreService contractStoreService;
private final Converter converter;
@GetMapping("/contract")
@SaCheckPermission(value = "contract:list", orRole = "admin")
......@@ -39,16 +37,28 @@ public class ContractController {
return contractService.list(dto);
}
@GetMapping("/contractPart")
@SaCheckPermission(value = "contract:listPart", orRole = "admin")
public Page<ContractVO> listPart(ContractDTO dto) {
return contractService.listPart(dto);
}
@GetMapping("/contract/{id}")
@SaCheckPermission(value = "contract:query", orRole = "admin")
public ContractVO getById(@PathVariable Long id) {
return converter.convert(contractService.getById(id), new ContractVO());
return contractService.getVOById(id);
}
@GetMapping("/contractByNo/{no}")
@SaCheckPermission(value = "contract:queryByNo", orRole = "admin")
public ContractVO getByNo(@PathVariable String no) {
return contractService.getByNo(no);
}
@PostMapping("/contract/{id}")
@SaCheckPermission(value = "contract:edit", orRole = "admin")
public String updateById(@PathVariable Long id, ContractDTO dto) {
return contractService.updateById(id, dto);
return contractService.updateById(id, null, dto);
}
@PostMapping("/contract/store")
......@@ -56,6 +66,9 @@ public class ContractController {
public String saveOrUpdateRContractStore(@RequestBody RContractStoreDTO dto) {
Assert.isFalse(ArrayUtil.isAllNotNull(dto.getStoreId(), dto.getContractId()), "合同id和项目id不能同时传值");
if (ObjUtil.isNotNull(dto.getContractId())) {
contractStoreService.lambdaUpdate()
.eq(RContractStore::getContractId, dto.getContractId())
.remove();
Opt.ofEmptyAble(dto.getStoreIds())
.ifPresent(storeIds -> {
List<RContractStore> contractStoreList = storeIds.stream()
......@@ -69,6 +82,9 @@ public class ContractController {
});
}
if (ObjUtil.isNotNull(dto.getStoreId())) {
contractStoreService.lambdaUpdate()
.eq(RContractStore::getStoreId, dto.getStoreId())
.remove();
Opt.ofEmptyAble(dto.getContractIds())
.ifPresent(contractIds -> {
List<RContractStore> contractStoreList = contractIds.stream()
......
......@@ -47,10 +47,10 @@ public class InspectController {
boolean result = inspectService.lambdaUpdate()
.eq(Inspect::getId, data.getId())
.set(Inspect::getStatus, data.getStatus())
.set(Inspect::getAuditTime, new Date())
.set(Inspect::getAuditDate, new Date())
.set(Inspect::getReviewer, data.getReviewer())
//审核状态为已完成的时候更新完成时间(0进行中、1待审核、2已完成、3、驳回)
.set(data.getStatus() == 2, Inspect::getFinishTime, new Date())
.set(data.getStatus() == 2, Inspect::getFinishDate, new Date())
.update();
if (result) {
return "更新巡检状态成功";
......
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vion.dto.InvoiceDTO;
import vion.service.IInvoiceService;
import vion.vo.InvoiceVO;
import java.util.List;
/**
* 发票记录管理
*/
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class InvoiceController {
private final IInvoiceService invoiceService;
private final Converter converter;
@GetMapping("/invoice")
@SaCheckPermission(value = "invoice:list", orRole = "admin")
public Page<InvoiceVO> list(InvoiceDTO dto) {
return invoiceService.list(dto);
}
@GetMapping("/invoice/{id}")
@SaCheckPermission(value = "invoice:query", orRole = "admin")
public InvoiceVO getById(@PathVariable Long id) {
return converter.convert(invoiceService.getById(id), new InvoiceVO());
}
@PostMapping("/invoice")
@SaCheckPermission(value = "invoice:save", orRole = "admin")
public String save(@RequestBody List<InvoiceDTO> dto) {
return invoiceService.save(dto);
}
@DeleteMapping("/invoice/{id}")
@SaCheckPermission(value = "invoice:remove", orRole = "admin")
public String delById(@PathVariable Long id) {
return invoiceService.removeById(id) ? "删除成功" : "删除失败";
}
}
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vion.dto.PaymentDTO;
import vion.service.IPaymentService;
import vion.vo.PaymentVO;
import java.util.List;
/**
* 收款记录管理
*/
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class PaymentController {
private final IPaymentService paymentService;
private final Converter converter;
@GetMapping("/payment")
@SaCheckPermission(value = "payment:list", orRole = "admin")
public Page<PaymentVO> list(PaymentDTO dto) {
return paymentService.list(dto);
}
@GetMapping("/payment/{id}")
@SaCheckPermission(value = "payment:query", orRole = "admin")
public PaymentVO getById(@PathVariable Long id) {
return converter.convert(paymentService.getById(id), new PaymentVO());
}
@PostMapping("/payment")
@SaCheckPermission(value = "payment:save", orRole = "admin")
public String save(@RequestBody List<PaymentDTO> dto) {
return paymentService.save(dto);
}
@DeleteMapping("/payment/{id}")
@SaCheckPermission(value = "payment:remove", orRole = "admin")
public String delById(@PathVariable Long id) {
return paymentService.removeById(id) ? "删除成功" : "删除失败";
}
}
......@@ -36,14 +36,14 @@ public class StoreController {
@GetMapping("/store")
@SaCheckPermission(value = "store:query", orRole = "admin")
public StoreVO getStoreById(@RequestParam Integer id) {
public StoreVO getStoreById(@RequestParam Long id) {
Store store = storeService.getById(id);
return converter.convert(store, StoreVO.class);
}
@GetMapping("/storeList")
@SaCheckPermission(value = "store:list1", orRole = "admin")
public List<StoreVO> getStoreList(Integer accountId, String name, Integer limit) {
public List<StoreVO> getStoreList(Long accountId, String name, Integer limit) {
List<Store> storeList = storeService.lambdaQuery()
.eq(ObjUtil.isNotNull(accountId), Store::getAccountId, accountId)
.like(StrUtil.isNotBlank(name), Store::getName, name)
......@@ -56,7 +56,8 @@ public class StoreController {
@SaCheckPermission(value = "store:editAndSave", orRole = "admin")
public String saveOrUpdate(@RequestBody StoreDTO data, @RequestHeader String token) {
UserVO user = Global.USERNAME_MAP.get(token);
// 创建项目时,默认维保状态为 --
data.setMaintainStatus("--");
Store store = converter.convert(data, Store.class);
if (data.getId() != null) {
store.setModifyUser(user.getId());
......@@ -68,14 +69,20 @@ public class StoreController {
@PostMapping("/updateStoreStatus")
@SaCheckPermission(value = "store:editStatus", orRole = "admin")
public Object updateStoreStage(StatusDTO statusDTO, @RequestHeader String token) {
public Object updateStoreStage(@RequestBody StatusDTO statusDTO, @RequestHeader String token) {
return storeService.updateStoreStage(statusDTO, token);
}
@PostMapping("/store/bindContract")
@SaCheckPermission(value = "store:bindContract", orRole = "admin")
// todo 权限未加
public String setMasterContract(@RequestBody StoreDTO dto) {
return storeService.updateById(converter.convert(dto, new Store())) ? "绑定主合同成功" : "绑定主合同失败";
}
@GetMapping("/store/manualCal")
@SaCheckPermission(value = "store:calMaintainStatus", orRole = "admin")
// todo 权限未加
public String manualCalMaintainStatus() {
return storeService.calMaintainStatus();
}
}
......@@ -56,9 +56,8 @@ public class UserController {
@GetMapping("/user/onlyName")
@SaCheckPermission(value = "user:listName", orRole = "admin")
// todo 权限未加
public List<UserVO> getNameList(UserDTO dto) {
return converter.convert(userService.list(Wrappers.lambdaQuery(converter.convert(dto, new User())).select(User::getId, User::getUsername)), UserVO.class);
return converter.convert(userService.list(Wrappers.lambdaQuery(converter.convert(dto, new User())).select(User::getId, User::getUsername, User::getPreWorkOrder)), UserVO.class);
}
@GetMapping("/user")
......@@ -102,9 +101,9 @@ public class UserController {
return dingMod.dingCallback(target, dto, res);
}
@GetMapping("/logout/{id}")
public String logout(@PathVariable Long id) {
StpUtil.logout(id);
@GetMapping("/logout")
public String logout() {
StpUtil.logout();
return "注销成功";
}
......
package vion.cron;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
......@@ -10,8 +11,8 @@ import vion.model.Dictionary;
import vion.service.IContractPaymentService;
import vion.service.IContractService;
import vion.service.IDictionaryService;
import vion.service.IStoreService;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
......@@ -24,15 +25,14 @@ import java.util.stream.Collectors;
* 从crm系统定时同步合同信息
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class ContractRunner {
@Resource
private IContractService contractService;
@Resource
private IDictionaryService dictionaryService;
@Resource
private IContractPaymentService contractPaymentService;
private final IContractService contractService;
private final IDictionaryService dictionaryService;
private final IContractPaymentService contractPaymentService;
private final IStoreService storeService;
@Scheduled(cron = "0 0 * * * *")
public Boolean contractSync() {
......@@ -160,9 +160,25 @@ public class ContractRunner {
}
contractPaymentService.saveBatch(contractPaymentList);
insertContractList.forEach(c -> {
String contractNo = c.getContractNo();
Contract exist = contractService.lambdaQuery().eq(Contract::getContractNo, contractNo).one();
Contract updDto = new Contract();
updDto.setId(exist.getId());
updDto.setPaidAmount(exist.getPaidAmount());
contractPaymentService.calMoney(exist, updDto);
contractService.updateById(updDto);
});
log.info("【结束】从crm系统同步合同信息");
return true;
}
@Scheduled(cron = "0 0 1 * * ?")
public void calMaintainStatus() {
log.info("【开始】计算门店维保状态");
storeService.calMaintainStatus();
log.info("【结束】计算门店维保状态");
}
}
......@@ -8,11 +8,11 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import vion.third.DingMod;
import vion.model.Task;
import vion.model.User;
import vion.service.ITaskService;
import vion.service.IUserService;
import vion.third.DingMod;
import java.util.List;
......
package vion.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
......@@ -123,6 +122,11 @@ public class ContractDTO extends BaseDTO {
private Integer warrantyPeriod;
/**
* 终验日期
*/
private Date finalDate;
/**
* 项目id
*/
private Long storeId;
......
......@@ -42,6 +42,8 @@ public class DeliveryRecordDTO extends BaseDTO {
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date signDate;
private String remark;
private MultipartFile[] files;
}
\ No newline at end of file
......@@ -16,8 +16,8 @@ public class InspectDTO extends BaseDTO {
private Long storeId;
/** 巡检时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date inspectTime;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date inspectDate;
/** 巡检方式(0远程、1现场) */
private Integer type;
......@@ -28,13 +28,13 @@ public class InspectDTO extends BaseDTO {
/** 审核人 */
private Integer reviewer;
/** 巡检时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date finishTime;
/** 完成时间 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date finishDate;
/** 审核时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date auditTime;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date auditDate;
/** 备注 */
private String remark;
......
package vion.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.Date;
@Getter
@Setter
public class InvoiceDTO extends BaseDTO {
private Long id;
/**
* 合同编号
*/
private String contractNo;
/**
* 开票时间
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date invoicingTime;
/**
* 发票金额
*/
private BigDecimal invoiceAmount;
/**
* 发票号
*/
private String invoiceNo;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package vion.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.Date;
/**
* 收款记录表
*/
@Getter
@Setter
public class PaymentDTO extends BaseDTO {
private Long id;
/**
* 合同编号
*/
private String contractNo;
/**
* 流水号
*/
private String serialNo;
/**
* 收款时间
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date collectionTime;
/**
* 收款金额
*/
private BigDecimal paymentAmount;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
......@@ -13,11 +13,5 @@ public class StatusDTO {
private Integer sourceType;
/** 来源id */
private Long sourceId;
/** 文件类型 */
private Integer type;
/** 名称 */
private String name;
/** 地址 */
private String url;
private MultipartFile[] files;
}
......@@ -13,7 +13,6 @@ import java.util.Date;
@Setter
public class StoreDTO extends BaseDTO {
private Long id;
private String storenum;
/** 门店名称 */
private String name ;
/** 销售人 */
......@@ -42,4 +41,6 @@ public class StoreDTO extends BaseDTO {
private Date enddate;
/** 主合同id */
private Long masterContract;
/** 维保状态 */
private String maintainStatus;
}
......@@ -53,7 +53,7 @@ public class TaskDTO extends BaseDTO {
private Long accountId;
private String uuid;
/** 预工单id */
private Long tasktempId;
private Long taskTempId;
private MultipartFile[] files;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
......
......@@ -11,11 +11,8 @@ public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaInterceptor(handle -> {
StpUtil.checkLogin();
}))
registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
.addPathPatterns("/api/**")
.excludePathPatterns("/api/dictionarys", "/api/accounts", "/api/users")
.excludePathPatterns("/api/upLoadFile", "/api/ding/callback/**", "/api/wechat/**", "/error")
.excludePathPatterns("/api/order/sign/*")
.excludePathPatterns("/api/taskTemp", "/api/taskTemp/wechatCallback");
......
......@@ -5,6 +5,7 @@ import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Opt;
import org.springframework.stereotype.Component;
import vion.model.Resource;
import vion.vo.RoleVO;
import vion.vo.UserVO;
......@@ -21,7 +22,9 @@ public class StpInterfaceImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
return userVO.getPermCodeList();
return Opt.ofEmptyAble(userVO.getResourceList())
.map(l -> l.stream().map(Resource::getPerm).collect(Collectors.toList()))
.orElse(ListUtil.empty());
}
@Override
......
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.Address;
public interface AddressMapper extends MPJBaseMapper<Address> {
}
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.ContractLog;
/**
* @author HlQ
* @date 2023/12/6
*/
public interface ContractLogMapper extends MPJBaseMapper<ContractLog> {
}
\ No newline at end of file
package vion.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.Invoice;
/**
* @author HlQ
* @date 2023/12/5
*/
public interface InvoiceMapper extends BaseMapper<Invoice>, MPJBaseMapper<Invoice> {
}
\ No newline at end of file
package vion.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.Payment;
/**
* @author HlQ
* @date 2023/12/5
*/
public interface PaymentMapper extends BaseMapper<Payment>, MPJBaseMapper<Payment> {
}
\ No newline at end of file
package vion.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 门店地址信息
*/
@Data
@TableName(value="tbl_address_info")
public class Address {
@TableId(value = "id", type = IdType.AUTO)
private Long id;//自增列
private Long storeId;//门店编码
private String consigneeName;//收货名称
private String consigneePhone;//收货手机号
private String consigneeAddress;//收货地址
private String contractName;//合同姓名
private String contractPhone;//合同手机号
private String contractAddress;//合同地址
private String invoiceName ;//发票姓名
private String invoicePhone;//发票手机号
private String invoiceAddress;//发票地址
private String invoiceInfo;//开票信息
private String remark;//备注
}
......@@ -146,6 +146,18 @@ public class Contract {
private Integer warrantyPeriod;
/**
* 终验日期
*/
@TableField(value = "final_date")
private Date finalDate;
/**
* 开票金额
*/
@TableField(value = "invoice_amount")
private BigDecimal invoiceAmount;
/**
* 合同签订付款比例
*/
@TableField(exist = false)
......
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* @author HlQ
* @date 2023/12/6
*/
@Data
@TableName(value = "tbl_contract_log")
public class ContractLog {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 合同id
*/
@TableField(value = "contract_id")
private Long contractId;
/**
* 操作人
*/
@TableField(value = "\"operator\"")
private Long operator;
/**
* 操作内容
*/
@TableField(value = "content")
private String content;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
}
\ No newline at end of file
......@@ -53,6 +53,11 @@ public class DeliveryRecord {
private Date signDate;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
......
......@@ -2,9 +2,7 @@ package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import vion.vo.FaultLogVO;
import java.util.Date;
......@@ -13,7 +11,6 @@ import java.util.Date;
*/
@Data
@TableName(value="tbl_fault_log")
@AutoMapper(target = FaultLogVO.class)
public class FaultLog {
/** 自增列 */
@TableId(value = "id", type = IdType.AUTO)
......
......@@ -26,9 +26,9 @@ public class Inspect {
private Long storeId;
/** 巡检时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@OrderBy
private Date inspectTime;
private Date inspectDate;
/** 巡检方式(0远程、1现场) */
private Integer type;
......@@ -40,14 +40,14 @@ public class Inspect {
private Integer reviewer;
/** 巡检时间 */
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date finishTime;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date finishDate;
/** 审核时间 */
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date auditTime;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date auditDate;
/** 创建时间 */
@TableField(value = "create_time", fill = FieldFill.INSERT)
......
package vion.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import lombok.Data;
import vion.dto.InvoiceDTO;
import vion.vo.InvoiceVO;
import java.math.BigDecimal;
import java.util.Date;
/**
* 发票记录表
*/
@Data
@TableName(value = "tbl_invoice")
@AutoMappers({
@AutoMapper(target = InvoiceVO.class),
@AutoMapper(target = InvoiceDTO.class),
})
public class Invoice {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 合同编号
*/
@TableField(value = "contract_no")
private String contractNo;
/**
* 开票时间
*/
@TableField(value = "invoicing_time")
private Date invoicingTime;
/**
* 发票金额
*/
@TableField(value = "invoice_amount")
private BigDecimal invoiceAmount;
/**
* 发票号
*/
@TableField(value = "invoice_no")
private String invoiceNo;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@TableField(value = "create_time")
private Date createTime;
@TableField(value = "update_time")
private Date updateTime;
}
\ No newline at end of file
package vion.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import lombok.Data;
import vion.dto.PaymentDTO;
import vion.vo.PaymentVO;
import java.math.BigDecimal;
import java.util.Date;
/**
* 收款记录表
*/
@Data
@TableName(value = "tbl_payment")
@AutoMappers({
@AutoMapper(target = PaymentVO.class),
@AutoMapper(target = PaymentDTO.class),
})
public class Payment {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 合同编号
*/
@TableField(value = "contract_no")
private String contractNo;
/**
* 流水号
*/
@TableField(value = "serial_no")
private String serialNo;
/**
* 收款时间
*/
@TableField(value = "collection_time")
private Date collectionTime;
/**
* 收款金额
*/
@TableField(value = "payment_amount")
private BigDecimal paymentAmount;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@TableField(value = "create_time")
private Date createTime;
@TableField(value = "update_time")
private Date updateTime;
}
\ No newline at end of file
......@@ -22,7 +22,6 @@ import java.util.Date;
public class Store {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String storenum;
/** 门店名称 */
@TableField(condition = SqlCondition.LIKE)
private String name;
......@@ -59,4 +58,7 @@ public class Store {
/** 主合同id */
private Long masterContract;
/** 维保状态 */
private String maintainStatus;
}
package vion.service;
import com.github.yulichang.base.MPJBaseService;
import vion.model.Address;
import vion.model.ContractLog;
public interface IContractLogService extends MPJBaseService<ContractLog> {
public interface IAddressService extends MPJBaseService<Address> {
}
\ No newline at end of file
package vion.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.PathVariable;
import vion.dto.ContractDTO;
import vion.model.Contract;
import com.github.yulichang.base.MPJBaseService;
......@@ -14,6 +15,12 @@ public interface IContractService extends MPJBaseService<Contract>{
Page<ContractVO> list(ContractDTO dto);
String updateById(Long id, ContractDTO dto);
Page<ContractVO> listPart(ContractDTO dto);
ContractVO getVOById(Long id);
ContractVO getByNo(@PathVariable String no);
String updateById(Long id, String contractNo, ContractDTO dto);
}
\ No newline at end of file
package vion.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseService;
import vion.dto.InvoiceDTO;
import vion.model.Invoice;
import vion.vo.InvoiceVO;
import java.util.List;
public interface IInvoiceService extends MPJBaseService<Invoice> {
Page<InvoiceVO> list(InvoiceDTO dto);
String save(List<InvoiceDTO> dto);
}
package vion.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseService;
import vion.dto.PaymentDTO;
import vion.model.Payment;
import vion.vo.PaymentVO;
import java.util.List;
public interface IPaymentService extends MPJBaseService<Payment> {
Page<PaymentVO> list(PaymentDTO dto);
String save(List<PaymentDTO> dto);
}
......@@ -13,4 +13,6 @@ public interface IStoreService extends MPJBaseService<Store> {
String updateStoreStage(StatusDTO statusDTO, String token);
String calMaintainStatus();
}
......@@ -2,10 +2,11 @@ package vion.service.impl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.springframework.stereotype.Service;
import vion.mapper.AddressMapper;
import vion.model.Address;
import vion.service.IAddressService;
import vion.mapper.ContractLogMapper;
import vion.model.ContractLog;
import vion.service.IContractLogService;
@Service
public class AddressServiceImpl extends MPJBaseServiceImpl<AddressMapper, Address> implements IAddressService {
public class ContractLogServiceImpl extends MPJBaseServiceImpl<ContractLogMapper, ContractLog> implements IContractLogService {
}
......@@ -22,20 +22,27 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class ContractPaymentServiceImpl extends MPJBaseServiceImpl<ContractPaymentMapper, ContractPayment> implements IContractPaymentService {
/**
* 当合同状态变化或者应收款变化时,重新计算款项
*
* @param exitContract
* @param dto
*/
@Override
public void calMoney(Contract exitContract, Contract dto) {
List<ContractPayment> contractPaymentList = this.lambdaQuery().eq(ContractPayment::getContractId, dto.getId()).list();
List<ContractPayment> contractPaymentList = this.lambdaQuery().eq(ContractPayment::getContractId, exitContract.getId()).list();
Map<Integer, BigDecimal> type2RatioMap = contractPaymentList.stream().collect(Collectors.toMap(ContractPayment::getPaymentType, ContractPayment::getPaymentRatio));
Integer status = dto.getStatus() == null ? exitContract.getStatus() : dto.getStatus();
BigDecimal sumRatio = new BigDecimal(0);
for (int i = 1; i <= status; i++) {
BigDecimal ratio = type2RatioMap.get(i);
NumberUtil.add(ratio, sumRatio);
sumRatio = NumberUtil.add(ratio, sumRatio);
}
BigDecimal totalAmount = exitContract.getTotalAmount();
BigDecimal curAmount = NumberUtil.mul(totalAmount, sumRatio);
BigDecimal recAmount = NumberUtil.sub(curAmount, dto.getPaidAmount() != null ? dto.getPaidAmount() : exitContract.getPaidAmount());
BigDecimal outsideAmount = NumberUtil.sub(totalAmount, recAmount);
BigDecimal paidAmount = dto.getPaidAmount() == null ? exitContract.getPaidAmount() : dto.getPaidAmount();
BigDecimal recAmount = NumberUtil.sub(curAmount, paidAmount);
BigDecimal outsideAmount = NumberUtil.sub(totalAmount, NumberUtil.add(paidAmount, recAmount));
dto.setReceivableAmount(recAmount);
dto.setOutstandingAmount(outsideAmount);
}
......
......@@ -5,26 +5,28 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vion.dto.ContractDTO;
import vion.mapper.ContractMapper;
import vion.model.Contract;
import vion.model.FileInfo;
import vion.model.RContractStore;
import vion.model.Store;
import vion.model.*;
import vion.service.*;
import vion.vo.ContractVO;
import vion.vo.StoreVO;
import vion.vo.UserVO;
import java.io.File;
......@@ -33,6 +35,7 @@ import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
......@@ -46,6 +49,7 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
private final IFileService fileService;
private final IContractPaymentService contractPaymentService;
private final IRContractStoreService contractStoreService;
private final IContractLogService contractLogService;
private final Converter converter;
@Value("${fileUrl:}")
......@@ -54,13 +58,28 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
@Override
public Page<ContractVO> list(ContractDTO dto) {
Contract contract = converter.convert(dto, new Contract());
Page<Contract> contractList = this.lambdaQuery(contract)
.orderByDesc(Contract::getModifyTime)
.page(Page.of(dto.getPageNum(), dto.getPageSize()));
List<ContractVO> contractVOList = converter.convert(contractList.getRecords(), ContractVO.class);
// 查出合同关联的项目名
completeStoreName(contractVOList);
return Page.<ContractVO>of(contractList.getCurrent(), contractList.getSize(), contractList.getTotal()).setRecords(contractVOList);
}
@Override
public Page<ContractVO> listPart(ContractDTO dto) {
Contract contract = converter.convert(dto, new Contract());
List<Long> ids = Opt.ofNullable(dto.getStoreId())
.map(storeId -> contractStoreService.listObjs(Wrappers.<RContractStore>lambdaQuery().select(RContractStore::getContractId).eq(RContractStore::getStoreId, dto.getStoreId()), o -> Long.valueOf(o.toString())))
.orElse(ListUtil.empty());
.filter(CollUtil::isNotEmpty)
.orElse(ListUtil.of(0L));
Page<Contract> contractList = this.lambdaQuery(contract)
.select(Contract::getId, Contract::getName, Contract::getContractNo, Contract::getType, Contract::getSignDate, Contract::getWarrantyPeriod, Contract::getFinalDate, Contract::getStatus, Contract::getSaleName, Contract::getCustomerName)
.in(CollUtil.isNotEmpty(ids), Contract::getId, ids)
.orderByDesc(Contract::getModifyTime)
.page(Page.of(dto.getPageNum(), dto.getPageSize()));
List<ContractVO> contractVOList = converter.convert(contractList.getRecords(), ContractVO.class);
// 查出合同关联的项目名
......@@ -79,25 +98,77 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
.filter(MapUtil::isNotEmpty)
.map(map -> map.values().stream().flatMap(List::stream).collect(Collectors.toList()))
.map(storeIds -> Db.listByIds(storeIds, Store.class))
.map(storeList -> storeList.stream().collect(Collectors.toMap(Store::getId, Store::getName)))
.ifPresent(storeIdNameMap -> contractVOList.forEach(contractVO -> {
.map(storeList -> storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity())))
.ifPresent(storeId2StoreMap -> contractVOList.forEach(contractVO -> {
if (contractStoreIdsMap.containsKey(contractVO.getId())) {
contractVO.setStoreNames(contractStoreIdsMap.get(contractVO.getId()).stream().map(storeIdNameMap::get).collect(Collectors.toList()));
List<StoreVO> storeVOS = converter.convert(contractStoreIdsMap.get(contractVO.getId()).stream().map(storeId2StoreMap::get).collect(Collectors.toList()), StoreVO.class);
contractVO.setStoreVOS(storeVOS);
}
}));
}
@Override
public ContractVO getVOById(Long id) {
MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<Contract>()
.selectAll(Contract.class)
.selectCollection(ContractLog.class, ContractVO::getContractLogs)
.leftJoin(ContractLog.class, ContractLog::getContractId, Contract::getId)
.eq(Contract::getId, id);
return this.selectJoinOne(ContractVO.class, wrapper);
}
@Override
public ContractVO getByNo(String no) {
Contract contract = this.lambdaQuery()
.select(Contract::getId, Contract::getName, Contract::getContractNo, Contract::getType, Contract::getSignDate, Contract::getWarrantyPeriod, Contract::getFinalDate, Contract::getStatus, Contract::getSaleName, Contract::getCustomerName)
.eq(Contract::getContractNo, no)
.one();
ContractVO contractVO = converter.convert(contract, new ContractVO());
Assert.notNull(contractVO, "合同不存在");
MPJLambdaWrapper<RContractStore> wrapper = new MPJLambdaWrapper<RContractStore>()
.select(Store::getId, Store::getName)
.leftJoin(Store.class, Store::getId, RContractStore::getStoreId)
.eq(RContractStore::getContractId, contract.getId());
List<StoreVO> storeVOS = contractStoreService.selectJoinList(StoreVO.class, wrapper);
contractVO.setStoreVOS(storeVOS);
return contractVO;
}
@Override
public String updateById(Long id, ContractDTO dto) {
Contract exitContract = this.getById(id);
@Transactional(rollbackFor = Exception.class)
public String updateById(Long id, String contractNo, ContractDTO dto) {
Contract exitContract = null;
if (ObjUtil.isNotNull(id)) {
exitContract = this.getById(id);
} else if (StrUtil.isNotBlank(contractNo)) {
exitContract = this.lambdaQuery().eq(Contract::getContractNo, contractNo).one();
}
Assert.notNull(exitContract, "合同不存在");
Contract contract = converter.convert(dto, new Contract());
contract.setId(id);
if ((ObjUtil.notEqual(contract.getStatus(), exitContract.getStatus()) && contract.getStatus() != null) || dto.getPaidAmount() != null) {
contract.setId(exitContract.getId());
contractPaymentService.calMoney(exitContract, contract);
}
this.updateById(contract);
if (this.updateById(contract)) {
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
ContractLog contractLog = new ContractLog();
contractLog.setContractId(contract.getId());
if (dto.getStatus() == 1) {
contractLog.setContent("合同:已签订");
} else if (dto.getStatus() == 2) {
contractLog.setContent("合同:已到货");
} else if (dto.getStatus() == 3) {
contractLog.setContent("合同:系统验收");
} else if (dto.getStatus() == 4) {
contractLog.setContent("合同:项目验收");
} else if (dto.getStatus() == 5) {
contractLog.setContent("合同:质保");
} else if (dto.getStatus() == 6) {
contractLog.setContent("合同:维保");
}
contractLog.setOperator(userVO.getId());
contractLogService.save(contractLog);
Opt.ofNullable(dto.getFiles())
.ifPresent(fileList ->
......@@ -127,5 +198,8 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
fileService.save(fileInfo);
}));
return "更新成功";
} else {
return "更新失败";
}
}
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
......@@ -12,11 +13,13 @@ import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import vion.dto.ContractDTO;
import vion.dto.DeliveryRecordDTO;
import vion.mapper.DeliveryRecordMapper;
import vion.model.DeliveryRecord;
import vion.model.FileInfo;
import vion.model.Store;
import vion.service.IContractService;
import vion.service.IDeliveryRecordService;
import vion.service.IFileService;
import vion.vo.DeliveryRecordVO;
......@@ -36,6 +39,7 @@ import java.util.Date;
public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecordMapper, DeliveryRecord> implements IDeliveryRecordService {
private final IFileService fileService;
private final IContractService contractService;
private final Converter converter;
@Value("${fileUrl:}")
......@@ -45,7 +49,7 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
public Page<DeliveryRecordVO> list(DeliveryRecordDTO dto) {
MPJLambdaWrapper<DeliveryRecord> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, new DeliveryRecord()))
.selectAll(DeliveryRecord.class)
.select(Store::getName)
.selectAs(Store::getName, DeliveryRecordVO::getStoreName)
.leftJoin(Store.class, Store::getId, DeliveryRecord::getStoreId);
return this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), DeliveryRecordVO.class, wrapper);
}
......@@ -54,6 +58,10 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
public String save(DeliveryRecordDTO dto) {
DeliveryRecord record = converter.convert(dto, new DeliveryRecord());
if (this.save(record)) {
ContractDTO contractDTO = new ContractDTO();
contractDTO.setStatus(2);
contractService.updateById(null, dto.getContractNo(), contractDTO);
Opt.ofNullable(dto.getFiles())
.ifPresent(fileList -> {
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
......@@ -63,7 +71,8 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
String fileName = orgName.substring(0, orgName.lastIndexOf("."));
String fileExt = orgName.substring(orgName.lastIndexOf("."));
String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt;
String path = fileUrl + FileUtil.FILE_SEPARATOR + "/delivery" + FileUtil.FILE_SEPARATOR + dto.getStoreId() + FileUtil.FILE_SEPARATOR + record.getId() + FileUtil.FILE_SEPARATOR + filename;
Long storeId = ObjUtil.isNull(dto.getStoreId()) ? 0L : dto.getStoreId();
String path = fileUrl + FileUtil.FILE_SEPARATOR + "/delivery" + FileUtil.FILE_SEPARATOR + storeId + FileUtil.FILE_SEPARATOR + record.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path);
try {
infile.transferTo(file);
......@@ -72,7 +81,7 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
}
FileInfo fileInfo = new FileInfo();
fileInfo.setStoreId(dto.getStoreId());
fileInfo.setStoreId(storeId);
fileInfo.setSourceId(record.getId());
fileInfo.setSourceType(6);
fileInfo.setName(filename);
......
......@@ -27,7 +27,7 @@ public class InspectServiceImpl extends MPJBaseServiceImpl<InspectMapper, Inspec
@Override
public Page<Inspect> getInspectList(InspectDTO data) {
Page<Inspect> inspectList = this.lambdaQuery(converter.convert(data, new Inspect()))
.between(data.getStartdate() != null && data.getEnddate() != null, Inspect::getInspectTime, data.getStartdate(), data.getEnddate())
.between(data.getStartdate() != null && data.getEnddate() != null, Inspect::getInspectDate, data.getStartdate(), data.getEnddate())
.page(Page.of(data.getPageNum(), data.getPageSize()));
List<Store> storeList = storeService.list();
......
package vion.service.impl;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vion.dto.InvoiceDTO;
import vion.mapper.InvoiceMapper;
import vion.model.Contract;
import vion.model.Invoice;
import vion.service.IContractService;
import vion.service.IInvoiceService;
import vion.vo.InvoiceVO;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author HlQ
* @date 2023/12/5
*/
@Service
@RequiredArgsConstructor
public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoice> implements IInvoiceService {
private final IContractService contractService;
private final Converter converter;
@Override
public Page<InvoiceVO> list(InvoiceDTO dto) {
Page<Invoice> recPage = this.lambdaQuery(converter.convert(dto, new Invoice())).page(Page.of(dto.getPageNum(), dto.getPageSize()));
return Page.<InvoiceVO>of(recPage.getCurrent(), recPage.getSize(), recPage.getTotal()).setRecords(converter.convert(recPage.getRecords(), InvoiceVO.class));
}
@Override
@Transactional(rollbackFor = Exception.class)
public String save(List<InvoiceDTO> dto) {
List<Invoice> invoiceList = converter.convert(dto, Invoice.class);
this.saveBatch(invoiceList);
Map<String, List<Invoice>> no2InvoiceMap = invoiceList.stream().collect(Collectors.groupingBy(Invoice::getContractNo));
no2InvoiceMap.forEach((no, list) -> {
BigDecimal sum = list.stream().map(Invoice::getInvoiceAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
// 根据合同编号查合同
Contract existContract = contractService.lambdaQuery().eq(Contract::getContractNo, no).one();
contractService.lambdaUpdate().eq(Contract::getContractNo, no).set(Contract::getInvoiceAmount, NumberUtil.add(sum, existContract.getInvoiceAmount())).update();
});
return "成功";
}
}
package vion.service.impl;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vion.dto.PaymentDTO;
import vion.mapper.PaymentMapper;
import vion.model.Contract;
import vion.model.Payment;
import vion.service.IContractPaymentService;
import vion.service.IContractService;
import vion.service.IPaymentService;
import vion.vo.PaymentVO;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author HlQ
* @date 2023/12/5
*/
@Service
@RequiredArgsConstructor
public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Payment> implements IPaymentService {
private final IContractService contractService;
private final IContractPaymentService contractPaymentService;
private final Converter converter;
@Override
public Page<PaymentVO> list(PaymentDTO dto) {
Page<Payment> recPage = this.lambdaQuery(converter.convert(dto, new Payment())).page(Page.of(dto.getPageNum(), dto.getPageSize()));
return Page.<PaymentVO>of(recPage.getCurrent(), recPage.getSize(), recPage.getTotal()).setRecords(converter.convert(recPage.getRecords(), PaymentVO.class));
}
@Override
@Transactional(rollbackFor = Exception.class)
public String save(List<PaymentDTO> dto) {
List<Payment> paymentList = converter.convert(dto, Payment.class);
paymentList.forEach(p -> {
Payment payment = this.lambdaQuery().eq(Payment::getSerialNo, p.getSerialNo()).one();
if (ObjUtil.isNull(payment)) {
this.save(p);
} else {
p.setId(payment.getId());
this.updateById(p);
}
});
Map<String, List<Payment>> no2PaymentMap = paymentList.stream().collect(Collectors.groupingBy(Payment::getContractNo));
no2PaymentMap.forEach((no, list) -> {
BigDecimal sumAmount = list.stream().map(Payment::getPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
Contract exitContract = contractService.lambdaQuery().eq(Contract::getContractNo, no).one();
// 最新的应收款去计算
Contract updDto = new Contract();
updDto.setId(exitContract.getId());
updDto.setPaidAmount(sumAmount);
contractPaymentService.calMoney(exitContract, updDto);
contractService.updateById(updDto);
});
return "成功";
}
}
......@@ -43,7 +43,9 @@ public class ResourceServiceImpl extends MPJBaseServiceImpl<ResourceMapper, Reso
@Override
public List<Tree<Long>> listTree(Long id) {
List<Resource> resourceList = this.list();
List<Resource> resourceList = this.lambdaQuery()
.orderByAsc(Resource::getSortCode)
.list();
List<TreeNode<Long>> nodeList = CollUtil.newArrayList();
resourceList.forEach(v -> {
......
......@@ -6,6 +6,8 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
......@@ -28,10 +30,7 @@ import vion.vo.StoreVO;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
......@@ -100,23 +99,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
storeVO.setContractCount(Opt.ofEmptyAble(contractStores).map(List::size).orElse(0));
Contract masterContract = id2ContractMap.getOrDefault(item.getMasterContract(), null);
storeVO.setMainContract(Opt.ofNullable(masterContract).map(c -> converter.convert(c, new ContractVO())).orElse(null));
/*if (CollUtil.isEmpty(contractStores)) {
storeVO.setMaintainStatus("--");
} else {
List<Long> contractIds = contractStores.stream().map(RContractStore::getContractId).collect(Collectors.toList());
Set<Boolean> maintainStatusSet = new HashSet<>();
contractIds.forEach(id -> {
Contract contract = id2ContractMap.get(id);
Date maintainSdate = contract.getMaintainSdate();
Date maintainEdate = contract.getMaintainEdate();
if (ArrayUtil.isAllNotNull(maintainSdate, maintainEdate)) {
boolean isIn = DateUtil.isIn(new Date(), maintainSdate, maintainEdate);
maintainStatusSet.add(isIn);
}
});
// todo 维保状态每天定时任务计算
storeVO.setMaintainStatus(CollUtil.isEmpty(maintainStatusSet) ? "--" : maintainStatusSet.contains(true) ? "在保" : "脱保");
}*/
// 补充服务单
if (store2TaskIdMap.containsKey(item.getId())) {
List<ServiceOrder> serviceOrders = store2TaskIdMap.get(item.getId())
......@@ -133,7 +116,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
public String updateStoreStage(StatusDTO statusDTO, String token) {
this.update(Wrappers.<Store>lambdaUpdate()
.set(Store::getProjectStage, statusDTO.getProjectStage())
.eq(Store::getId, statusDTO.getSourceId()));
.eq(Store::getId, statusDTO.getStoreId()));
Opt.ofNullable(statusDTO.getFiles()).ifPresent(tmpFiles -> {
for (MultipartFile infile : tmpFiles) {
......@@ -165,4 +148,65 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
});
return "更新成功";
}
@Override
public String calMaintainStatus() {
List<Store> storeList = this.list();
Map<Long, List<Long>> storeId2ContractIdMap = Opt.ofEmptyAble(contractStoreService.list())
.map(l -> l.stream().collect(Collectors.groupingBy(RContractStore::getStoreId, Collectors.mapping(RContractStore::getContractId, Collectors.toList()))))
.orElse(MapUtil.empty());
List<Contract> contractList = contractService.listByIds(storeId2ContractIdMap.values().stream().flatMap(List::stream).collect(Collectors.toList()));
// 根据 storeList、storeId2ContractIdMap、contractList,得到一个storeId 为 key,List<Contract> 为 value 的 map
Map<Long, List<Contract>> storeId2ContractListMap = storeList.stream()
.collect(Collectors.toMap(Store::getId, store ->
storeId2ContractIdMap.getOrDefault(store.getId(), ListUtil.empty())
.stream()
.map(contractId -> contractList.stream().filter(contract -> contract.getId().equals(contractId)).findFirst().orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.toList())));
List<Store> updStoreList = new ArrayList<>();
for (Store s : storeList) {
s.setMaintainStatus("--");
List<Contract> contracts = storeId2ContractListMap.getOrDefault(s.getId(), ListUtil.empty());
if (CollUtil.isNotEmpty(contracts)) {
// 1.项目关联的主合同在维保期内,那么这个项目就是在保
Contract masterContract = contracts.stream().filter(contract -> ObjUtil.equals(contract.getId(), s.getMasterContract())).findFirst().orElse(null);
if (ObjUtil.isNotNull(masterContract)) {
Date finalDate = masterContract.getFinalDate();
Integer warrantyPeriod = masterContract.getWarrantyPeriod();
if (ArrayUtil.isAllNotNull(finalDate, warrantyPeriod)) {
Date finalDateEnd = DateUtil.offsetMonth(finalDate, warrantyPeriod);
boolean isIn = DateUtil.isIn(new Date(), finalDate, finalDateEnd);
if (isIn) {
s.setMaintainStatus("在保");
continue;
} else {
s.setMaintainStatus("脱保");
}
}
}
// 2.主合同脱保,那就判断维保合同
Set<Boolean> maintainStatusSet = new HashSet<>();
contracts.stream()
.filter(contract -> ObjUtil.equals(contract.getType(), 1))
.forEach(c -> {
Date maintainSdate = c.getMaintainSdate();
Date maintainEdate = c.getMaintainEdate();
if (ArrayUtil.isAllNotNull(maintainSdate, maintainEdate)) {
boolean isIn = DateUtil.isIn(new Date(), maintainSdate, maintainEdate);
maintainStatusSet.add(isIn);
}
});
s.setMaintainStatus(CollUtil.isEmpty(maintainStatusSet) ? s.getMaintainStatus() : maintainStatusSet.contains(true) ? "在保" : "脱保");
}
Store updStore = new Store();
updStore.setId(s.getId());
updStore.setMaintainStatus(s.getMaintainStatus());
updStoreList.add(updStore);
}
this.updateBatchById(updStoreList);
return "计算成功";
}
}
package vion.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
......@@ -22,13 +24,13 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vion.Global;
import vion.dto.TaskDTO;
import vion.mapper.ServiceOrderMapper;
import vion.mapper.TaskMapper;
import vion.model.Dictionary;
import vion.model.*;
import vion.service.*;
import vion.third.DingMod;
import vion.third.WechatMod;
import vion.vo.RoleVO;
import vion.vo.TaskTempVO;
import vion.vo.TaskVO;
import vion.vo.UserVO;
......@@ -47,11 +49,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
private final IFaultLogService faultLogService;
private final IStoreService storeService;
private final IUserService userService;
private final IAccountService accountService;
private final IDictionaryService dictionaryService;
// 循环依赖,这里用mapper
// private final MPJBaseServiceOrderService serviceOrderService;
private final ServiceOrderMapper serviceOrderMapper;
private final DingMod dingMod;
private final WechatMod wechatMod;
private final Converter converter;
......@@ -60,30 +58,29 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
@Override
public Page<TaskVO> getTaskList(TaskDTO data) {
/*Page<Task> taskList = this
.lambdaQuery(converter.convert(data, new Task()))
.between(data.getStartdate() != null && data.getEnddate() != null, Task::getRepairTime, data.getStartdate(), data.getEnddate())
.lt(data.getCurDate() != null, Task::getExpDate, data.getCurDate())
.page(Page.of(data.getPageNum(), data.getPageSize()));
// todo 是否加入缓存
List<Store> storeList = storeService.list();
List<Account> accountList = accountService.list();
List<TaskVO> taskVOList = new ArrayList<>();
Map<Long, ServiceOrder> taskId2OrderMap = Opt.ofEmptyAble(taskList.getRecords())
.map(l -> l.stream().map(Task::getId).collect(Collectors.toList()))
.map(idList -> serviceOrderMapper.selectList(Wrappers.<ServiceOrder>lambdaQuery().in(ServiceOrder::getTaskId, idList)))
.map(serviceOrderList -> serviceOrderList.stream().collect(Collectors.toMap(ServiceOrder::getTaskId, Function.identity())))
.orElse(MapUtil.empty());
Opt.ofEmptyAble(taskList.getRecords())
.ifPresent(l -> l.forEach(v -> {
TaskVO taskVO = converter.convert(v, TaskVO.class);
taskVO.setStoreName(storeList.stream().filter(s -> s.getId().equals(v.getStoreId())).map(Store::getName).findFirst().orElse("--"));
taskVO.setAccountName(accountList.stream().filter(a -> a.getId().equals(v.getAccountId())).map(Account::getName).findFirst().orElse("--"));
taskVO.setServiceOrder(taskId2OrderMap.get(v.getId()));
taskVOList.add(taskVO);
}));*/
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
Set<Long> taskIdSet = CollUtil.newHashSet();
Opt.ofEmptyAble(userVO.getRoleVOList())
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toList()))
.map(roleCodeList -> {
if (CollUtil.contains(roleCodeList, "task_admin") || CollUtil.contains(roleCodeList, "admin")) {
FaultLog log = new FaultLog();
log.setTaskId(0L);
return ListUtil.of(log);
} else {
List<FaultLog> logList = faultLogService.lambdaQuery()
.select(FaultLog::getTaskId)
.in(FaultLog::getOperator, userVO.getId())
.list();
if (CollUtil.isEmpty(logList)) {
FaultLog log = new FaultLog();
log.setTaskId(-99L);
logList.add(log);
}
return logList;
}
})
.ifPresent(logs -> taskIdSet.addAll(logs.stream().map(FaultLog::getTaskId).collect(Collectors.toSet())));
MPJLambdaWrapper<Task> wrapper = new MPJLambdaWrapper<>(converter.convert(data, new Task()))
.selectAll(Task.class)
......@@ -95,6 +92,13 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
.leftJoin(ServiceOrder.class, ServiceOrder::getTaskId, Task::getId)
.between(data.getStartdate() != null && data.getEnddate() != null, Task::getRepairTime, data.getStartdate(), data.getEnddate())
.lt(data.getCurDate() != null, Task::getExpDate, data.getCurDate());
if (taskIdSet.size() == 1 && CollUtil.get(taskIdSet, 0).equals(-99L)) {
// 不是管理员,并且第一次处理工单,但当前处理人是他
} else if (taskIdSet.size() == 1 && CollUtil.get(taskIdSet, 0).equals(0L)) {
// 管理员逻辑
} else {
wrapper.in(Task::getId, taskIdSet);
}
return this.selectJoinListPage(Page.of(data.getPageNum(), data.getPageSize()), TaskVO.class, wrapper);
}
......@@ -102,7 +106,9 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
public TaskVO getTaskById(Long taskId) {
MPJLambdaWrapper<Task> wrapper = new MPJLambdaWrapper<Task>()
.selectAll(Task.class)
.selectAs(Store::getName, TaskVO::getStoreName)
.selectCollection(FileInfo.class, TaskTempVO::getFileList)
.leftJoin(Store.class, Store::getId, Task::getStoreId)
.leftJoin(FileInfo.class, on -> on
.eq(FileInfo::getSourceId, Task::getId)
.eq(FileInfo::getStoreId, Task::getStoreId))
......@@ -121,25 +127,18 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
}
// 可能直接提工单,而不是预工单确认之后生成的工单
if (data.getTasktempId() != null) {
if (data.getTaskTempId() != null) {
taskTempService.lambdaUpdate()
.set(TaskTemp::getStatus, 3)
.set(TaskTemp::getOperator, data.getActiveUser())
.set(TaskTemp::getStoreId, data.getStoreId())
.eq(TaskTemp::getId, data.getTasktempId())
.eq(TaskTemp::getId, data.getTaskTempId())
.update();
//根据预处理工单更新附件的门店ID
/*fileService.lambdaUpdate()
.set(FileInfo::getStoreId, data.getStoreId())
.eq(FileInfo::getSourceId, data.getId())
.update();*/
}
if (data.getId() == null) {
//添加新工单
task.setUuid(IdUtil.nanoId());
task.setTaskTempId(data.getTasktempId());
this.save(task);
List<FaultLog> saveList = new ArrayList<>();
......@@ -149,6 +148,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
faultLog.setStoreId(task.getStoreId());
faultLog.setOperator(-1L);
faultLog.setContent(data.getRepairPeople() + "|提交工单");
faultLog.setCreateTime(task.getRepairTime());
saveList.add(faultLog);
//添加工单处理日志
......
......@@ -310,8 +310,7 @@ public class DingMod {
.map(rrList -> rrList.stream().map(RRoleResource::getResourceId).collect(Collectors.toList()))
.ifPresent(resourceIdList -> {
List<Resource> resourceList = resourceService.listByIds(resourceIdList);
List<String> permCodeList = resourceList.stream().map(Resource::getPerm).collect(Collectors.toList());
userVO.setPermCodeList(permCodeList);
userVO.setResourceList(resourceList);
});
}
......
package vion.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import vion.model.ContractLog;
import java.math.BigDecimal;
import java.util.Date;
......@@ -121,7 +121,19 @@ public class ContractVO {
private Integer warrantyPeriod;
/**
* 终验日期
*/
private Date finalDate;
/**
* 开票金额
*/
private BigDecimal invoiceAmount;
/**
* 合同关联的项目名
*/
private List<String> storeNames;
private List<StoreVO> storeVOS;
private List<ContractLog> contractLogs;
}
\ No newline at end of file
......@@ -42,6 +42,11 @@ public class DeliveryRecordVO {
private Date signDate;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
......
package vion.vo;
import lombok.Data;
import java.util.Date;
@Data
public class FaultLogVO {
private Long id;//自增列
private Long storeId;//门店id
private Long taskId;//工单id
private Integer operator;//操作者
private String content;//操作内容
private Date createTime;//创建时间
private String remark;//备注
private String filename;//文件名称
private String fileurl;//文件url
}
package vion.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.Date;
@Getter
@Setter
public class InvoiceVO {
private Long id;
/**
* 合同编号
*/
private String contractNo;
/**
* 开票时间
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date invoicingTime;
/**
* 发票金额
*/
private BigDecimal invoiceAmount;
/**
* 发票号
*/
private String invoiceNo;
/**
* 备注
*/
private String remark;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
}
\ No newline at end of file
package vion.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.Date;
@Getter
@Setter
public class PaymentVO {
private Long id;
/**
* 合同编号
*/
private String contractNo;
/**
* 流水号
*/
private String serialNo;
/**
* 收款时间
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date collectionTime;
/**
* 收款金额
*/
private BigDecimal paymentAmount;
/**
* 备注
*/
private String remark;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
}
\ No newline at end of file
......@@ -8,13 +8,10 @@ import java.util.Date;
@Data
public class StoreVO {
private Long id;
private String storenum;
/** 门店名称 */
private String name;
/** 销售人 */
private Integer salesperson;
/** 质保期 */
private Integer warrantyPeriod;
/** 客户姓名 */
private String customerName;
/** 实施类型:0纯供货、1供货+安装、3续保、4维修 */
......@@ -38,27 +35,6 @@ public class StoreVO {
/** 集团id */
private Long accountId;
/* *//** 收货名称 *//*
private String consigneeName;
*//** 收货手机号 *//*
private String consigneePhone;
*//** 收货地址 *//*
private String consigneeAddress;
*//** 合同姓名 *//*
private String contractName;
*//** 合同手机号 *//*
private String contractPhone;
*//** 合同地址 *//*
private String contractAddress;
*//** 发票姓名 *//*
private String invoiceName ;
*//** 发票手机号 *//*
private String invoicePhone;
*//** 发票地址 *//*
private String invoiceAddress;
*//** 开票信息 *//*
private String invoiceInfo;*/
private String accountName;
private Long fileNum;
/** 维保状态(在保、脱保、--) */
......
......@@ -16,7 +16,7 @@ public class TaskVO {
/** 门店名称 */
private String storeName;
/** 预处理工单id */
private Long tasktempId;
private Long taskTempId;
/** 报修日期 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date repairTime;
......
......@@ -3,6 +3,7 @@ package vion.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import vion.model.Resource;
import java.util.Date;
import java.util.List;
......@@ -33,7 +34,7 @@ public class UserVO {
private String token;
/** 权限码列表 */
private List<String> permCodeList;
private List<Resource> resourceList;
private List<RoleVO> roleVOList;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!