Merge branch 'test' into feauture-20261104
# Conflicts: # bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcProfitReportServiceImpl.java
This commit is contained in:
@@ -305,6 +305,14 @@ public class BillingController extends BaseController
|
||||
return success(task);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:orderBill:rebill')")
|
||||
@Log(title = "Order bill local rebill cancel", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/orderBill/rebill/task/{taskId}/cancel")
|
||||
public AjaxResult cancelLocalRebill(@PathVariable("taskId") String taskId)
|
||||
{
|
||||
return success(prcOrderBillService.cancelLocalRebill(taskId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Order no options for remote-search dropdown (bill list multi search).
|
||||
*/
|
||||
|
||||
+453
@@ -0,0 +1,453 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.price.service.support.UploadFileBatch;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.MessageUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.price.domain.PrcCustomerPriceSet;
|
||||
import com.bms.price.domain.PrcCustomerPriceSetBatch;
|
||||
import com.bms.price.domain.PrcPriceExcelFile;
|
||||
import com.bms.price.domain.PrcPriceSet;
|
||||
import com.bms.price.domain.PrcPriceSetDetail;
|
||||
import com.bms.price.domain.PrcPriceSetSaveTask;
|
||||
import com.bms.price.domain.PrcPriceSetVersion;
|
||||
import com.bms.price.service.IPrcPriceExcelFileService;
|
||||
import com.bms.price.service.IPrcPriceSetService;
|
||||
|
||||
/**
|
||||
* Exclusive quote (shares prc_price_set with PACKAGE)
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/exclusive")
|
||||
public class ExclusiveQuoteController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IPrcPriceSetService priceSetService;
|
||||
|
||||
@Autowired
|
||||
private IPrcPriceExcelFileService priceExcelFileService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(PrcPriceSet set)
|
||||
{
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
startPage();
|
||||
List<PrcPriceSet> list = priceSetService.selectPrcPriceSetList(set);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:query')")
|
||||
@GetMapping("/{priceSetId:[0-9]+}")
|
||||
public AjaxResult getInfo(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
return success(priceSetService.selectPrcPriceSetById(priceSetId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:add')")
|
||||
@Log(title = "Exclusive quote", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody PrcPriceSet set)
|
||||
{
|
||||
if (set.getPriceSetId() != null)
|
||||
{
|
||||
priceSetService.assertSetCategory(set.getPriceSetId(), PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
}
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
set.setCreateBy(getUsername());
|
||||
set.setUpdateBy(getUsername());
|
||||
String taskId = priceSetService.submitSaveAsync(set);
|
||||
// Do not pass bare String to success(): overload puts it into msg, not data.
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:query')")
|
||||
@GetMapping("/save/task/{taskId}")
|
||||
public AjaxResult getSaveTask(@PathVariable String taskId)
|
||||
{
|
||||
PrcPriceSetSaveTask task = priceSetService.getSaveTask(taskId);
|
||||
if (task == null)
|
||||
{
|
||||
return error(MessageUtils.message("price.set.save.task.notExists"));
|
||||
}
|
||||
return success(task);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody PrcPriceSet set)
|
||||
{
|
||||
priceSetService.assertSetCategory(set.getPriceSetId(), PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
set.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updatePrcPriceSet(set));
|
||||
}
|
||||
|
||||
/** Update package name and note only. */
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote basic", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/basic")
|
||||
public AjaxResult editBasic(@RequestBody PrcPriceSet set)
|
||||
{
|
||||
priceSetService.assertSetCategory(set.getPriceSetId(), PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
set.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updateBasicInfo(set));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:remove')")
|
||||
@Log(title = "Exclusive quote", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{priceSetIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] priceSetIds)
|
||||
{
|
||||
if (priceSetIds != null)
|
||||
{
|
||||
for (Long id : priceSetIds)
|
||||
{
|
||||
priceSetService.assertSetCategory(id, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
return toAjax(priceSetService.deletePrcPriceSetByIds(priceSetIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:audit')")
|
||||
@Log(title = "Exclusive quote提交审核", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/submit/{priceSetId}")
|
||||
public AjaxResult submit(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
return toAjax(priceSetService.submit(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:audit')")
|
||||
@Log(title = "Exclusive quote生效", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/approve/{priceSetId}")
|
||||
public AjaxResult approve(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
return toAjax(priceSetService.approve(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:audit')")
|
||||
@Log(title = "Exclusive quote驳回", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/reject/{priceSetId}")
|
||||
public AjaxResult reject(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
return toAjax(priceSetService.reject(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote version activate", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/version/activate/{psvId}")
|
||||
public AjaxResult activateVersion(@PathVariable Long psvId, @RequestBody(required = false) PrcPriceSetVersion body)
|
||||
{
|
||||
Date effectiveTime = body == null ? null : body.getEffectiveTime();
|
||||
return toAjax(priceSetService.activateVersion(psvId, effectiveTime, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:add')")
|
||||
@Log(title = "Exclusive quote version copy", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/version/copy/{psvId}")
|
||||
public AjaxResult copyVersion(@PathVariable Long psvId)
|
||||
{
|
||||
Long newPsvId = priceSetService.copyVersion(psvId, getUsername());
|
||||
return success(newPsvId);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:add')")
|
||||
@Log(title = "Exclusive quote version create", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/version/create/{priceSetId}")
|
||||
public AjaxResult createVersion(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
Long newPsvId = priceSetService.createVersion(priceSetId, getUsername());
|
||||
return success(newPsvId);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote version delete", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/version/{psvId}")
|
||||
public AjaxResult deleteVersion(@PathVariable Long psvId)
|
||||
{
|
||||
return toAjax(priceSetService.deleteVersion(psvId, getUsername()));
|
||||
}
|
||||
|
||||
/** Import excel attachments for a version (prc_price_excel_file.psv_id). */
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:list')")
|
||||
@GetMapping("/version/{psvId}/excelFiles")
|
||||
public AjaxResult versionExcelFiles(@PathVariable Long psvId)
|
||||
{
|
||||
List<PrcPriceExcelFile> list = priceExcelFileService.selectByPsvId(psvId);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:audit')")
|
||||
@Log(title = "Exclusive quote disable", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/disable/{priceSetId}")
|
||||
public AjaxResult disable(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
return toAjax(priceSetService.disable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:audit')")
|
||||
@Log(title = "Exclusive quote enable", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/enable/{priceSetId}")
|
||||
public AjaxResult enable(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
return toAjax(priceSetService.enable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:add')")
|
||||
@Log(title = "Exclusive quote copy", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/copy/{priceSetId}")
|
||||
public AjaxResult copy(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
Long id = priceSetService.copy(priceSetId, getUsername());
|
||||
return success(id);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:query')")
|
||||
@PostMapping("/validate")
|
||||
public AjaxResult validate(@RequestBody PrcPriceSet set)
|
||||
{
|
||||
return success(priceSetService.validate(set));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:list')")
|
||||
@GetMapping("/detail/list")
|
||||
public TableDataInfo detailList(PrcPriceSetDetail detail)
|
||||
{
|
||||
startPage();
|
||||
List<PrcPriceSetDetail> list = priceSetService.selectDetailList(detail);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/** All detail rows for one product (no page); used by edit-price drawer. */
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:list')")
|
||||
@GetMapping("/detail/byProduct")
|
||||
public AjaxResult detailByProduct(@RequestParam("psvId") Long psvId,
|
||||
@RequestParam("productCode") String productCode)
|
||||
{
|
||||
return success(priceSetService.selectDetailListByProduct(psvId, productCode));
|
||||
}
|
||||
|
||||
/** All detail rows for a version (no page); batch prefetch instead of N byProduct calls. */
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:list')")
|
||||
@GetMapping("/detail/byVersion")
|
||||
public AjaxResult detailByVersion(@RequestParam("psvId") Long psvId)
|
||||
{
|
||||
return success(priceSetService.selectDetailListByVersion(psvId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 版本明细搜索下拉选项:按版本去重后的 产品/国家/分区
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:list')")
|
||||
@GetMapping("/detail/options")
|
||||
public AjaxResult detailOptions(@RequestParam("psvId") Long psvId)
|
||||
{
|
||||
return success(priceSetService.selectDetailOptions(psvId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit')")
|
||||
@Log(title = "Exclusive quote明细", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/detail")
|
||||
public AjaxResult addDetail(@RequestBody PrcPriceSetDetail detail)
|
||||
{
|
||||
return toAjax(priceSetService.insertDetail(detail));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit')")
|
||||
@Log(title = "Exclusive quote明细", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/detail")
|
||||
public AjaxResult editDetail(@RequestBody PrcPriceSetDetail detail)
|
||||
{
|
||||
return toAjax(priceSetService.updateDetail(detail));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit')")
|
||||
@Log(title = "Exclusive quote价格导入", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/detail/importPrices")
|
||||
public AjaxResult importDetailPrices(
|
||||
@RequestParam(value = "files", required = false) MultipartFile[] files,
|
||||
@RequestParam(value = "file", required = false) MultipartFile file,
|
||||
@RequestParam("priceSetId") Long priceSetId,
|
||||
@RequestParam(value = "psvId", required = false) Long psvId,
|
||||
@RequestParam(value = "updateOnly", required = false, defaultValue = "false") boolean updateOnly,
|
||||
@RequestParam(value = "replaceByProductCountry", required = false, defaultValue = "false") boolean replaceByProductCountry,
|
||||
@RequestParam(value = "countryCode", required = false) String countryCode)
|
||||
throws Exception
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
String taskId = priceSetService.submitImportDetailPricesAsync(priceSetId, psvId, UploadFileBatch.collect(files, file),
|
||||
getUsername(), updateOnly, replaceByProductCountry, countryCode);
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview pull product library (no DB write). For create wizard before finish.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit') or @ss.hasPermi('price:exclusive:add')")
|
||||
@PostMapping("/detail/previewPullFromLibrary")
|
||||
public AjaxResult previewPullFromLibrary()
|
||||
{
|
||||
return success(priceSetService.previewPullFromLibrary());
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview Excel import (no DB write). Optional detailsJson for updateOnly / build-price merge.
|
||||
* Optional countryCode = single-country dedicated-line Excel (same as product country import).
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit') or @ss.hasPermi('price:exclusive:add')")
|
||||
@PostMapping("/detail/previewImportPrices")
|
||||
public AjaxResult previewImportPrices(
|
||||
@RequestParam(value = "files", required = false) MultipartFile[] files,
|
||||
@RequestParam(value = "file", required = false) MultipartFile file,
|
||||
@RequestParam(value = "updateOnly", required = false, defaultValue = "false") boolean updateOnly,
|
||||
@RequestParam(value = "replaceByProductCountry", required = false, defaultValue = "false") boolean replaceByProductCountry,
|
||||
@RequestParam(value = "countryCode", required = false) String countryCode,
|
||||
@RequestParam(value = "detailsJson", required = false) String detailsJson) throws Exception
|
||||
{
|
||||
java.util.List<MultipartFile> batch = UploadFileBatch.collect(files, file);
|
||||
java.util.List<byte[]> bytesList = new java.util.ArrayList<byte[]>();
|
||||
java.util.List<String> names = new java.util.ArrayList<String>();
|
||||
for (MultipartFile item : batch)
|
||||
{
|
||||
bytesList.add(item.getBytes());
|
||||
names.add(item.getOriginalFilename());
|
||||
}
|
||||
List<PrcPriceSetDetail> existing = null;
|
||||
if (StringUtils.isNotEmpty(detailsJson))
|
||||
{
|
||||
existing = com.alibaba.fastjson2.JSON.parseArray(detailsJson, PrcPriceSetDetail.class);
|
||||
}
|
||||
return success(priceSetService.previewImportDetailPricesMany(
|
||||
bytesList, names, updateOnly, existing, replaceByProductCountry, countryCode, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Async pull product library into version details. Returns taskId; poll /save/task/{taskId}.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit')")
|
||||
@Log(title = "Exclusive quote拉取产品", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/detail/pullFromLibrary")
|
||||
public AjaxResult pullFromLibrary(@RequestParam("priceSetId") Long priceSetId,
|
||||
@RequestParam(value = "psvId", required = false) Long psvId,
|
||||
@RequestParam(value = "force", required = false, defaultValue = "false") boolean force)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
String taskId = priceSetService.submitPullFromLibraryAsync(priceSetId, psvId, force, getUsername());
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Async batch write of detail surcharge snapshots. Returns taskId; poll /save/task/{taskId}.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit')")
|
||||
@Log(title = "Exclusive quote附加费", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/detail/surcharge/async")
|
||||
public AjaxResult batchSurchargeAsync(@RequestBody List<PrcPriceSetDetail> details)
|
||||
{
|
||||
String taskId = priceSetService.submitDetailSurchargeAsync(details);
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit') or @ss.hasPermi('price:exclusive:forceEdit')")
|
||||
@Log(title = "Exclusive quote明细", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/detail/{psdIds}")
|
||||
public AjaxResult removeDetail(@PathVariable Long[] psdIds)
|
||||
{
|
||||
return toAjax(priceSetService.deleteDetailByIds(psdIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:list')")
|
||||
@GetMapping("/customer/list")
|
||||
public TableDataInfo customerList(PrcCustomerPriceSet customer)
|
||||
{
|
||||
startPage();
|
||||
List<PrcCustomerPriceSet> list = priceSetService.selectCustomerList(customer);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote客户绑定", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/customer")
|
||||
public AjaxResult addCustomer(@RequestBody PrcCustomerPriceSet customer)
|
||||
{
|
||||
if (customer != null && customer.getPriceSetId() != null)
|
||||
{
|
||||
priceSetService.assertSetCategory(customer.getPriceSetId(), PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
}
|
||||
customer.setCreateBy(getUsername());
|
||||
return toAjax(priceSetService.insertCustomer(customer));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote客户批量绑定", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/customer/batch")
|
||||
public AjaxResult batchAddCustomer(@RequestBody PrcCustomerPriceSetBatch batch)
|
||||
{
|
||||
if (batch != null && batch.getPriceSetId() != null)
|
||||
{
|
||||
priceSetService.assertSetCategory(batch.getPriceSetId(), PrcPriceSet.CATEGORY_EXCLUSIVE);
|
||||
}
|
||||
batch.setCreateBy(getUsername());
|
||||
batch.setUpdateBy(getUsername());
|
||||
return success(priceSetService.batchInsertCustomers(batch));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote客户绑定", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/customer")
|
||||
public AjaxResult editCustomer(@RequestBody PrcCustomerPriceSet customer)
|
||||
{
|
||||
customer.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updateCustomer(customer));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:exclusive:edit')")
|
||||
@Log(title = "Exclusive quote客户绑定", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/customer/{customerPricesetIds}")
|
||||
public AjaxResult removeCustomer(@PathVariable Long[] customerPricesetIds)
|
||||
{
|
||||
return toAjax(priceSetService.deleteCustomerByIds(customerPricesetIds));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,6 +55,8 @@ public class PriceSetController extends BaseController
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(PrcPriceSet set)
|
||||
{
|
||||
// Ordinary package module: never mix exclusive quotes into this list.
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_PACKAGE);
|
||||
startPage();
|
||||
List<PrcPriceSet> list = priceSetService.selectPrcPriceSetList(set);
|
||||
return getDataTable(list);
|
||||
@@ -64,6 +66,7 @@ public class PriceSetController extends BaseController
|
||||
@GetMapping("/{priceSetId:[0-9]+}")
|
||||
public AjaxResult getInfo(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_PACKAGE);
|
||||
return success(priceSetService.selectPrcPriceSetById(priceSetId));
|
||||
}
|
||||
|
||||
@@ -72,6 +75,11 @@ public class PriceSetController extends BaseController
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody PrcPriceSet set)
|
||||
{
|
||||
if (set.getPriceSetId() != null)
|
||||
{
|
||||
priceSetService.assertSetCategory(set.getPriceSetId(), PrcPriceSet.CATEGORY_PACKAGE);
|
||||
}
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_PACKAGE);
|
||||
set.setCreateBy(getUsername());
|
||||
set.setUpdateBy(getUsername());
|
||||
String taskId = priceSetService.submitSaveAsync(set);
|
||||
@@ -98,6 +106,8 @@ public class PriceSetController extends BaseController
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody PrcPriceSet set)
|
||||
{
|
||||
priceSetService.assertSetCategory(set.getPriceSetId(), PrcPriceSet.CATEGORY_PACKAGE);
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_PACKAGE);
|
||||
set.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updatePrcPriceSet(set));
|
||||
}
|
||||
@@ -108,6 +118,7 @@ public class PriceSetController extends BaseController
|
||||
@PutMapping("/basic")
|
||||
public AjaxResult editBasic(@RequestBody PrcPriceSet set)
|
||||
{
|
||||
priceSetService.assertSetCategory(set.getPriceSetId(), PrcPriceSet.CATEGORY_PACKAGE);
|
||||
set.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updateBasicInfo(set));
|
||||
}
|
||||
|
||||
+19
-4
@@ -32,6 +32,7 @@ import com.bms.common.utils.uuid.IdUtils;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
// 提成功能暂停使用:import com.bms.price.domain.PrcProfitCommissionRate;
|
||||
import com.bms.price.domain.PrcProfitReportExport;
|
||||
import com.bms.price.enums.ProfitAreaRule;
|
||||
import com.bms.price.domain.vo.PrcProfitReportOrderRow;
|
||||
import com.bms.price.domain.vo.PrcProfitReportProductRow;
|
||||
import com.bms.price.domain.vo.PrcProfitReportQuery;
|
||||
@@ -58,6 +59,14 @@ public class PrcProfitReportController extends BaseController
|
||||
return getDataTable(profitReportService.selectCustomerOptions(keywords));
|
||||
}
|
||||
|
||||
/** 客户区域字典值与毛利规则的映射。 */
|
||||
@PreAuthorize("@ss.hasPermi('report:profit:list')")
|
||||
@GetMapping("/area-rules")
|
||||
public AjaxResult areaRules()
|
||||
{
|
||||
return success(profitReportService.selectAreaRules());
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('report:profit:list')")
|
||||
@GetMapping("/summary")
|
||||
public AjaxResult summary(PrcProfitReportQuery query)
|
||||
@@ -118,7 +127,7 @@ public class PrcProfitReportController extends BaseController
|
||||
try
|
||||
{
|
||||
List<PrcProfitReportOrderRow> rows = profitReportService.selectOrderRows(query);
|
||||
return finishExport(export, rows, PrcProfitReportOrderRow.class, "订单毛利报表");
|
||||
return finishExport(export, rows, PrcProfitReportOrderRow.class, "订单毛利报表", query.getProfitRule());
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
@@ -136,7 +145,7 @@ public class PrcProfitReportController extends BaseController
|
||||
try
|
||||
{
|
||||
List<PrcProfitReportProductRow> rows = profitReportService.selectProductRows(query);
|
||||
return finishExport(export, rows, PrcProfitReportProductRow.class, "产品毛利报表");
|
||||
return finishExport(export, rows, PrcProfitReportProductRow.class, "产品毛利报表", query.getProfitRule());
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
@@ -200,7 +209,8 @@ public class PrcProfitReportController extends BaseController
|
||||
return export;
|
||||
}
|
||||
|
||||
private <T> AjaxResult finishExport(PrcProfitReportExport export, List<T> rows, Class<T> rowType, String sheetName)
|
||||
private <T> AjaxResult finishExport(PrcProfitReportExport export, List<T> rows, Class<T> rowType, String sheetName,
|
||||
String profitRule)
|
||||
{
|
||||
Path temp = null;
|
||||
try
|
||||
@@ -208,7 +218,12 @@ public class PrcProfitReportController extends BaseController
|
||||
temp = Files.createTempFile("profit-report-", ".xlsx");
|
||||
try (OutputStream output = Files.newOutputStream(temp))
|
||||
{
|
||||
new ExcelUtil<T>(rowType).exportExcelToStream(rows, sheetName, output);
|
||||
ExcelUtil<T> excelUtil = new ExcelUtil<>(rowType);
|
||||
if (ProfitAreaRule.GUANGZHOU.name().equals(profitRule))
|
||||
{
|
||||
excelUtil.hideColumn("costAmount", "redlineGrossProfit", "redlineGrossMarginRate");
|
||||
}
|
||||
excelUtil.exportExcelToStream(rows, sheetName, output);
|
||||
}
|
||||
String objectKey = "report/profit/" + DateUtils.datePath() + "/" + IdUtils.fastSimpleUUID() + ".xlsx";
|
||||
export.setStorageKey(ossStorage.upload(temp, objectKey,
|
||||
|
||||
@@ -224,6 +224,11 @@ price.bill.billingFail.weight=计费失败:销售价未匹配重量段
|
||||
price.bill.billingFail.catalogProduct=计费失败:产品价未匹配产品
|
||||
price.bill.billingFail.catalogCountry=计费失败:产品价未匹配国家
|
||||
price.bill.billingFail.catalogWeight=计费失败:产品价未匹配重量段
|
||||
price.bill.billingFail.packageNotEnabled=计费失败:套餐未启用
|
||||
price.bill.billingFail.noActivePackageVersion=计费失败:计费日无生效套餐版本
|
||||
price.bill.billingFail.noCustomerPackage=计费失败:客户未绑定套餐
|
||||
price.bill.packageNotEnabled=客户已绑定套餐但套餐未启用,无法计费
|
||||
price.quote.packageNotEnabled=客户已绑定套餐但套餐未启用,无法试算
|
||||
price.bill.export.filterRequired=请先设置列表查询条件后再导出
|
||||
price.bill.export.taskNotExists=导出任务不存在或已过期
|
||||
price.bill.export.tooMany=匹配订单超过上限 {0} 条,请缩小筛选范围
|
||||
@@ -232,3 +237,6 @@ price.bill.export.notReady=导出文件尚未生成或已失败
|
||||
price.bill.export.fileMissing=导出文件不存在或路径非法
|
||||
price.set.customer.batch.empty=请选择要绑定的客户
|
||||
price.set.customer.batch.done=批量绑定完成:共 {0} 个客户,新绑定 {1} 个,更换 {2} 个,跳过 {3} 个
|
||||
price.bill.recalc.taskCancelled=本地重新计费已取消
|
||||
price.bill.recalc.taskCancelNotRunning=任务已结束或不存在,无法取消
|
||||
price.bill.recalc.taskIdRequired=任务ID不能为空
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.bms.report;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.price.domain.vo.PrcProfitReportQuery;
|
||||
import com.bms.price.mapper.PrcProfitReportMapper;
|
||||
import com.bms.price.service.impl.PrcProfitReportServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
class ProfitAreaRuleTest
|
||||
{
|
||||
@Test
|
||||
void reportQueriesResolveRuleOnServerAndRejectUnknownAreas()
|
||||
{
|
||||
AtomicInteger calls = new AtomicInteger();
|
||||
PrcProfitReportMapper mapper = (PrcProfitReportMapper) Proxy.newProxyInstance(
|
||||
getClass().getClassLoader(), new Class<?>[] { PrcProfitReportMapper.class },
|
||||
(proxy, method, args) -> {
|
||||
calls.incrementAndGet();
|
||||
return Collections.emptyList();
|
||||
});
|
||||
PrcProfitReportServiceImpl service = new PrcProfitReportServiceImpl();
|
||||
ReflectionTestUtils.setField(service, "profitReportMapper", mapper);
|
||||
|
||||
PrcProfitReportQuery query = new PrcProfitReportQuery();
|
||||
query.setCustomerArea(" GZ ");
|
||||
query.setProfitRule("SHENZHEN");
|
||||
service.selectSummary(query);
|
||||
assertEquals("GZ", query.getCustomerArea());
|
||||
assertEquals("GUANGZHOU", query.getProfitRule());
|
||||
|
||||
query.setCustomerArea("C");
|
||||
query.setProfitRule("GUANGZHOU");
|
||||
service.selectOrderRows(query);
|
||||
assertEquals("SHENZHEN", query.getProfitRule());
|
||||
service.selectProductRows(query);
|
||||
assertEquals(3, calls.get());
|
||||
|
||||
query.setCustomerArea("UNKNOWN");
|
||||
assertThrows(ServiceException.class, () -> service.selectProductRows(query));
|
||||
query.setCustomerArea("");
|
||||
assertThrows(ServiceException.class, () -> service.selectSummary(query));
|
||||
assertEquals(3, calls.get());
|
||||
assertEquals("SHENZHEN", service.selectAreaRules().get("C"));
|
||||
assertEquals("GUANGZHOU", service.selectAreaRules().get("GZ"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user