feat: add editable order collaboration remarks
This commit is contained in:
@@ -44,12 +44,13 @@ public interface OrderCargoClient {
|
||||
Integer originalPackageCount, BigDecimal originalGrossWeightKg,
|
||||
BigDecimal originalVolumeCbm, String skuNo, String cargoNameEn,
|
||||
Integer unitsPerPackage, Integer totalQuantity, BigDecimal netWeightKg,
|
||||
String cargoRemark, String customerRemark, String latestInternalNote) {
|
||||
String cargoRemark, String customerRemark, String latestInternalNote,
|
||||
String warehouseRemark, String customerServiceRemark) {
|
||||
public CargoBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName,
|
||||
Integer originalPackageCount, BigDecimal originalGrossWeightKg,
|
||||
BigDecimal originalVolumeCbm) {
|
||||
this(cargoId, orderId, itemNo, cargoName, originalPackageCount,
|
||||
originalGrossWeightKg, originalVolumeCbm, null, null, null, null, null, null, null, null);
|
||||
originalGrossWeightKg, originalVolumeCbm, null, null, null, null, null, null, null, null, null, null);
|
||||
}
|
||||
public CargoBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName,
|
||||
Integer originalPackageCount, BigDecimal originalGrossWeightKg,
|
||||
@@ -58,7 +59,7 @@ public interface OrderCargoClient {
|
||||
String cargoRemark) {
|
||||
this(cargoId, orderId, itemNo, cargoName, originalPackageCount, originalGrossWeightKg,
|
||||
originalVolumeCbm, skuNo, cargoNameEn, unitsPerPackage, totalQuantity, netWeightKg,
|
||||
cargoRemark, null, null);
|
||||
cargoRemark, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -38,8 +38,8 @@ public class PlatformSmartLoadingController {
|
||||
public ApiResponse<Plan> recommend(@AuthenticationPrincipal AuthenticatedUser u,@PathVariable @Positive long planId,@Valid @RequestBody RecommendRequest r){FirstlegScopeGuard.platform(u);return ApiResponse.success(service.recommend(planId,r,u.userId(),u.username()));}
|
||||
@PatchMapping("/plans/{planId}/items/{itemId}") @PreAuthorize("hasAuthority('platform:firstleg:smart-loading:assign')")
|
||||
public ApiResponse<Plan> adjust(@AuthenticationPrincipal AuthenticatedUser u,@PathVariable @Positive long planId,@PathVariable @Positive long itemId,@Valid @RequestBody AdjustRequest r){FirstlegScopeGuard.platform(u);return ApiResponse.success(service.adjust(planId,itemId,r,u.userId(),u.username()));}
|
||||
@PatchMapping("/plans/{planId}/items/{itemId}/warehouse-remark") @PreAuthorize("hasAuthority('platform:firstleg:preload:edit')")
|
||||
public ApiResponse<Plan> warehouseRemark(@AuthenticationPrincipal AuthenticatedUser u,@PathVariable @Positive long planId,@PathVariable @Positive long itemId,@Valid @RequestBody WarehouseRemarkRequest r){FirstlegScopeGuard.platform(u);return ApiResponse.success(service.updateWarehouseRemark(planId,itemId,r,u.userId(),u.username()));}
|
||||
@PatchMapping("/plans/{planId}/items/{itemId}/remarks") @PreAuthorize("hasAuthority('platform:firstleg:preload:edit')")
|
||||
public ApiResponse<Plan> remarks(@AuthenticationPrincipal AuthenticatedUser u,@PathVariable @Positive long planId,@PathVariable @Positive long itemId,@Valid @RequestBody RemarksRequest r){FirstlegScopeGuard.platform(u);return ApiResponse.success(service.updateRemarks(planId,itemId,r,u.userId(),u.username()));}
|
||||
@DeleteMapping("/plans/{planId}/items/{itemId}") @PreAuthorize("hasAuthority('platform:firstleg:smart-loading:delete')")
|
||||
public ApiResponse<Plan> delete(@AuthenticationPrincipal AuthenticatedUser u,@PathVariable @Positive long planId,@PathVariable @Positive long itemId,@Valid @RequestBody DeleteRequest r){FirstlegScopeGuard.platform(u);return ApiResponse.success(service.delete(planId,itemId,r,u.userId(),u.username()));}
|
||||
@DeleteMapping("/plans/{planId}/unpicked-items") @PreAuthorize("hasAuthority('platform:firstleg:smart-loading:delete')")
|
||||
|
||||
@@ -240,6 +240,7 @@ public final class LoadingListDtos {
|
||||
String internalRemark,
|
||||
String customerRemark,
|
||||
String warehouseRemark,
|
||||
String customerServiceRemark,
|
||||
int loadSequence,
|
||||
LocalDateTime frozenAt,
|
||||
Integer itemVersion
|
||||
|
||||
@@ -83,7 +83,8 @@ public final class SmartLoadingDtos { private SmartLoadingDtos(){}
|
||||
@NotNull @Min(0) Integer expectedItemVersion,@NotBlank @Size(max=128) String operationId) {}
|
||||
public record RemoveUnpickedRequest(@NotNull @Min(0) Integer expectedPlanVersion,
|
||||
@NotBlank @Size(max=128) String operationId) {}
|
||||
public record WarehouseRemarkRequest(@Size(max=1000) String warehouseRemark,
|
||||
public record RemarksRequest(@Size(max=1000) String internalRemark,
|
||||
@Size(max=1000) String warehouseRemark, @Size(max=1000) String customerServiceRemark,
|
||||
@NotNull @Min(0) Integer expectedPlanVersion, @NotNull @Min(0) Integer expectedItemVersion,
|
||||
@NotBlank @Size(max=128) String operationId) {}
|
||||
public record PlanCoLoadGroup(Long groupId,String groupNo,Long lockedPlanId,Integer memberOrderCount,
|
||||
|
||||
@@ -9,7 +9,7 @@ public class LoadingPlanItemEntity {
|
||||
private String unitType; private Long palletId; private String palletNo; private Boolean indivisible;
|
||||
private Integer palletCount; private BigDecimal grossWeightKg; private BigDecimal netWeightKg; private BigDecimal dimensionalWeightKg; private BigDecimal volumeCbm;
|
||||
private String fbaTrackingNo; private String shipmentNo; private String shippingMark; private Integer loadSequence; private String positionSnapshot;
|
||||
private String internalRemark; private String customerRemark; private String warehouseRemark; private LocalDateTime frozenAt; private Long frozenBy;
|
||||
private String internalRemark; private String customerRemark; private String warehouseRemark; private String customerServiceRemark; private LocalDateTime frozenAt; private Long frozenBy;
|
||||
private Long removedBy; private String removedByName; private LocalDateTime removedAt; @TableLogic private Boolean deleted;
|
||||
@TableField(exist=false) private Long activeInboundDetailId;
|
||||
@TableField(exist=false) private Integer pickedPackageCount;
|
||||
|
||||
@@ -194,7 +194,7 @@ public interface LoadingListQueryMapper {
|
||||
* i.package_count / NULLIF(inbound.total_package_count,0)),0) pallet_count,
|
||||
gross_weight_kg, net_weight_kg, volume_cbm, dimensional_weight_kg,
|
||||
product_quantity, units_per_carton, fba_tracking_no, shipment_no,
|
||||
shipping_mark, internal_remark, customer_remark, warehouse_remark,
|
||||
shipping_mark, internal_remark, customer_remark, warehouse_remark, customer_service_remark,
|
||||
load_sequence, frozen_at, i.version AS item_version
|
||||
FROM fl_loading_plan_item i
|
||||
JOIN fl_loading_plan p ON p.id=i.loading_plan_id
|
||||
@@ -457,6 +457,7 @@ public interface LoadingListQueryMapper {
|
||||
private String internalRemark;
|
||||
private String customerRemark;
|
||||
private String warehouseRemark;
|
||||
private String customerServiceRemark;
|
||||
private Integer loadSequence;
|
||||
private LocalDateTime frozenAt;
|
||||
private Integer itemVersion;
|
||||
|
||||
@@ -11,7 +11,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstl
|
||||
int removeEditing(@Param("planId") long planId,@Param("itemId") long itemId,@Param("expectedVersion") int expectedVersion,@Param("operatorId") long operatorId,@Param("operatorName") String operatorName);
|
||||
@Update("""
|
||||
UPDATE fl_loading_plan_item i
|
||||
SET i.warehouse_remark=#{remark}, i.updated_by=#{operatorId}, i.updated_by_name=#{operatorName},
|
||||
SET i.internal_remark=#{internalRemark}, i.warehouse_remark=#{warehouseRemark},
|
||||
i.customer_service_remark=#{customerServiceRemark}, i.updated_by=#{operatorId}, i.updated_by_name=#{operatorName},
|
||||
i.updated_at=CURRENT_TIMESTAMP(3), i.version=i.version+1
|
||||
WHERE i.id=#{itemId} AND i.loading_plan_id=#{planId} AND i.deleted=0 AND i.frozen_at IS NULL
|
||||
AND i.version=#{expectedItemVersion}
|
||||
@@ -21,9 +22,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstl
|
||||
AND p.plan_status IN ('EDITING','LOADING')
|
||||
)
|
||||
""")
|
||||
int updateWarehouseRemark(@Param("planId") long planId, @Param("itemId") long itemId,
|
||||
int updateRemarks(@Param("planId") long planId, @Param("itemId") long itemId,
|
||||
@Param("touchedPlanVersion") int touchedPlanVersion,
|
||||
@Param("expectedItemVersion") int expectedItemVersion,
|
||||
@Param("remark") String remark, @Param("operatorId") long operatorId,
|
||||
@Param("internalRemark") String internalRemark,
|
||||
@Param("warehouseRemark") String warehouseRemark,
|
||||
@Param("customerServiceRemark") String customerServiceRemark,
|
||||
@Param("operatorId") long operatorId,
|
||||
@Param("operatorName") String operatorName);
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ public class LoadingListRepository {
|
||||
decimal(row.getGrossWeightKg()), decimal(row.getNetWeightKg()), decimal(row.getVolumeCbm()),
|
||||
decimal(row.getDimensionalWeightKg()), value(row.getProductQuantity()),
|
||||
integer(row.getUnitsPerCarton()), row.getFbaTrackingNo(), row.getShipmentNo(), row.getShippingMark(),
|
||||
row.getInternalRemark(), row.getCustomerRemark(), row.getWarehouseRemark(),
|
||||
row.getInternalRemark(), row.getCustomerRemark(), row.getWarehouseRemark(), row.getCustomerServiceRemark(),
|
||||
integer(row.getLoadSequence()), row.getFrozenAt(), row.getItemVersion())).toList();
|
||||
}
|
||||
|
||||
|
||||
@@ -147,10 +147,11 @@ public class SmartLoadingRepository {
|
||||
public int remove(long planId, long itemId, int version, long operatorId, String operatorName) {
|
||||
return items.removeEditing(planId, itemId, version, operatorId, operatorName);
|
||||
}
|
||||
public int updateWarehouseRemark(long planId, long itemId, int touchedPlanVersion, int expectedItemVersion,
|
||||
String remark, long operatorId, String operatorName) {
|
||||
return items.updateWarehouseRemark(planId, itemId, touchedPlanVersion, expectedItemVersion,
|
||||
remark, operatorId, operatorName);
|
||||
public int updateRemarks(long planId, long itemId, int touchedPlanVersion, int expectedItemVersion,
|
||||
String internalRemark, String warehouseRemark, String customerServiceRemark,
|
||||
long operatorId, String operatorName) {
|
||||
return items.updateRemarks(planId, itemId, touchedPlanVersion, expectedItemVersion,
|
||||
internalRemark, warehouseRemark, customerServiceRemark, operatorId, operatorName);
|
||||
}
|
||||
public int startPicking(long planId, long operatorId, String operatorName) {
|
||||
return plans.startPicking(planId, operatorId, operatorName);
|
||||
|
||||
@@ -1043,42 +1043,55 @@ public class SmartLoadingService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@BusinessAudit(event = "SMART_LOADING_WAREHOUSE_REMARK", resourceType = "LOADING_PLAN",
|
||||
resourceId = "#planId", description = "修改装柜仓库备注")
|
||||
public Plan updateWarehouseRemark(long planId, long itemId, WarehouseRemarkRequest request,
|
||||
long operatorId, String operatorName) {
|
||||
@BusinessAudit(event = "SMART_LOADING_REMARKS", resourceType = "LOADING_PLAN",
|
||||
resourceId = "#planId", description = "修改装柜协作备注")
|
||||
public Plan updateRemarks(long planId, long itemId, RemarksRequest request,
|
||||
long operatorId, String operatorName) {
|
||||
String operation = operation(request.operationId());
|
||||
String remark = trim(request.warehouseRemark());
|
||||
if (!StringUtils.hasText(remark)) remark = null;
|
||||
String requestHash = sha256("WAREHOUSE_REMARK|" + planId + '|' + itemId + '|'
|
||||
+ Objects.toString(remark, "") + '|' + request.expectedPlanVersion() + '|'
|
||||
String internalRemark = nullableRemark(request.internalRemark());
|
||||
String warehouseRemark = nullableRemark(request.warehouseRemark());
|
||||
String customerServiceRemark = nullableRemark(request.customerServiceRemark());
|
||||
String requestHash = sha256("REMARKS|" + planId + '|' + itemId + '|'
|
||||
+ Objects.toString(internalRemark, "") + '|' + Objects.toString(warehouseRemark, "") + '|'
|
||||
+ Objects.toString(customerServiceRemark, "") + '|' + request.expectedPlanVersion() + '|'
|
||||
+ request.expectedItemVersion());
|
||||
Plan replay = replay(operation, planId, "WAREHOUSE_REMARK", itemId, requestHash);
|
||||
Plan replay = replay(operation, planId, "REMARKS", itemId, requestHash);
|
||||
if (replay != null) return replay;
|
||||
LoadingPlanEntity plan = editing(planId, request.expectedPlanVersion(), operatorId, operatorName);
|
||||
LoadingPlanItemEntity item = repository.item(planId, itemId);
|
||||
if (item == null) throw new BizException(ResultCode.NOT_FOUND, "装柜明细不存在");
|
||||
if (Objects.equals(item.getWarehouseRemark(), remark)) {
|
||||
if (Objects.equals(item.getInternalRemark(), internalRemark)
|
||||
&& Objects.equals(item.getWarehouseRemark(), warehouseRemark)
|
||||
&& Objects.equals(item.getCustomerServiceRemark(), customerServiceRemark)) {
|
||||
return view(plan, requireBooking(plan.getContainerBookingId()));
|
||||
}
|
||||
String before = json(values("warehouseRemark", item.getWarehouseRemark(), "version", item.getVersion()));
|
||||
String before = json(values("internalRemark", item.getInternalRemark(),
|
||||
"warehouseRemark", item.getWarehouseRemark(), "customerServiceRemark", item.getCustomerServiceRemark(),
|
||||
"version", item.getVersion()));
|
||||
try {
|
||||
touch(plan, operatorId, operatorName);
|
||||
if (repository.updateWarehouseRemark(planId, itemId, request.expectedPlanVersion() + 1,
|
||||
request.expectedItemVersion(), remark, operatorId, operatorName) != 1) {
|
||||
if (repository.updateRemarks(planId, itemId, request.expectedPlanVersion() + 1,
|
||||
request.expectedItemVersion(), internalRemark, warehouseRemark, customerServiceRemark,
|
||||
operatorId, operatorName) != 1) {
|
||||
throw conflict("装柜计划或明细已被其他人修改,请刷新后重试");
|
||||
}
|
||||
} catch (DataAccessException exception) {
|
||||
if (hasSqlState(exception, "45000")) {
|
||||
throw conflict("装柜计划或明细状态已变化,仓库备注未保存,请刷新后重试");
|
||||
throw conflict("装柜计划或明细状态已变化,备注未保存,请刷新后重试");
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
history(planId, itemId, "WAREHOUSE_REMARK", plan.getPlanStatus(), plan.getPlanStatus(), operation,
|
||||
before, json(values("warehouseRemark", remark, "requestHash", requestHash)), operatorId, operatorName);
|
||||
history(planId, itemId, "REMARKS", plan.getPlanStatus(), plan.getPlanStatus(), operation,
|
||||
before, json(values("internalRemark", internalRemark, "warehouseRemark", warehouseRemark,
|
||||
"customerServiceRemark", customerServiceRemark, "requestHash", requestHash)), operatorId, operatorName);
|
||||
return view(repository.plan(planId), requireBooking(plan.getContainerBookingId()));
|
||||
}
|
||||
|
||||
private static String nullableRemark(String value) {
|
||||
String remark = trim(value);
|
||||
return StringUtils.hasText(remark) ? remark : null;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@BusinessAudit(event = "SMART_LOADING_ITEM_DELETE", resourceType = "LOADING_PLAN_ITEM",
|
||||
resourceId = "#itemId", description = "删除智能装柜明细")
|
||||
@@ -1384,7 +1397,12 @@ public class SmartLoadingService {
|
||||
i.setNetWeightKg(unit(c.unitNetWeightKg()).multiply(BigDecimal.valueOf(count)));
|
||||
i.setVolumeCbm(unit(c.unitVolumeCbm()).multiply(BigDecimal.valueOf(count)));
|
||||
i.setPalletCount(estimatedPalletCount(c, count));
|
||||
applyCargo(i, cargo, count); i.setLoadSequence(seq); i.setDeleted(false); i.setCreatedBy(op); i.setCreatedByName(name); i.setUpdatedBy(op); i.setUpdatedByName(name); i.setVersion(0); return i;
|
||||
applyCargo(i, cargo, count);
|
||||
i.setCustomerRemark(cargo.customerRemark());
|
||||
i.setInternalRemark(cargo.latestInternalNote());
|
||||
i.setWarehouseRemark(cargo.warehouseRemark());
|
||||
i.setCustomerServiceRemark(cargo.customerServiceRemark());
|
||||
i.setLoadSequence(seq); i.setDeleted(false); i.setCreatedBy(op); i.setCreatedByName(name); i.setUpdatedBy(op); i.setUpdatedByName(name); i.setVersion(0); return i;
|
||||
}
|
||||
private int estimatedPalletCount(Candidate candidate, int packageCount) {
|
||||
InboundOrderEntity inbound = repository.inbound(candidate.accountId(), candidate.inboundId());
|
||||
@@ -1397,8 +1415,6 @@ public class SmartLoadingService {
|
||||
item.setSkuCode(cargo.skuNo());
|
||||
item.setProductNameEn(cargo.cargoNameEn());
|
||||
item.setUnitsPerCarton(cargo.unitsPerPackage());
|
||||
item.setCustomerRemark(cargo.customerRemark());
|
||||
item.setInternalRemark(cargo.latestInternalNote());
|
||||
int original = cargo.originalPackageCount() == null || cargo.originalPackageCount() <= 0
|
||||
? boxes : cargo.originalPackageCount();
|
||||
if (cargo.unitsPerPackage() != null) {
|
||||
@@ -1419,9 +1435,7 @@ public class SmartLoadingService {
|
||||
&& Objects.equals(current.getSkuCode(), desired.getSkuCode())
|
||||
&& Objects.equals(current.getProductNameEn(), desired.getProductNameEn())
|
||||
&& Objects.equals(current.getUnitsPerCarton(), desired.getUnitsPerCarton())
|
||||
&& Objects.equals(current.getProductQuantity(), desired.getProductQuantity())
|
||||
&& Objects.equals(current.getCustomerRemark(), desired.getCustomerRemark())
|
||||
&& Objects.equals(current.getInternalRemark(), desired.getInternalRemark());
|
||||
&& Objects.equals(current.getProductQuantity(), desired.getProductQuantity());
|
||||
}
|
||||
|
||||
private static boolean decimalEquals(BigDecimal left, BigDecimal right) {
|
||||
@@ -1434,7 +1448,8 @@ public class SmartLoadingService {
|
||||
"palletCount", item.getPalletCount(), "skuCode", item.getSkuCode(),
|
||||
"productNameEn", item.getProductNameEn(), "unitsPerCarton", item.getUnitsPerCarton(),
|
||||
"productQuantity", item.getProductQuantity(), "customerRemark", item.getCustomerRemark(),
|
||||
"internalRemark", item.getInternalRemark(), "version", item.getVersion());
|
||||
"internalRemark", item.getInternalRemark(), "warehouseRemark", item.getWarehouseRemark(),
|
||||
"customerServiceRemark", item.getCustomerServiceRemark(), "version", item.getVersion());
|
||||
}
|
||||
|
||||
private OrderCargoClient.CargoBinding loadCargo(Candidate candidate) {
|
||||
|
||||
Reference in New Issue
Block a user