package biz.book.writer;
|
|
import java.math.BigDecimal;
|
import java.util.Date;
|
import java.util.List;
|
|
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.Logger;
|
|
import biz.book.BookCommand;
|
import biz.book.BookCommandBucket;
|
import biz.book.BookCommandMeta;
|
import biz.book.BookResult;
|
import biz.book.FlowTable;
|
import biz.book.FreezeCondition;
|
import biz.book.OrderRight;
|
import biz.book.QtyCommand;
|
import biz.book.RecordOperator;
|
import foundation.dao.DataPackage;
|
import foundation.dao.DataSource;
|
import foundation.data.entity.Entity;
|
import foundation.data.entity.EntitySet;
|
import foundation.data.entity.Filter;
|
import foundation.data.object.DataObject;
|
import foundation.data.object.EntitySaver;
|
import foundation.persist.NamedSQL;
|
import foundation.persist.SQLRunner;
|
import foundation.token.IOnlineUser;
|
import foundation.util.ID;
|
import foundation.util.Util;
|
import foundation.workflow.ActionProvider;
|
|
public class FeeBookWriter extends ActionProvider {
|
|
private static Logger logger;
|
public static final String FieldName_BatchMark = "batch_mark";
|
|
static {
|
logger = LogManager.getLogger(FeeBookWriter.class);
|
}
|
|
public FeeBookWriter() {
|
|
}
|
|
@Override
|
protected void publishMethod() {
|
//1. 获取库存记账描述列表
|
addMethod("getBookCommandList");
|
|
//2. 获取库存记账描述
|
addMethod("getBookCommand");
|
|
//3. 记账
|
addMethod("write");
|
}
|
|
public void getBookCommandList() {
|
BookCommandBucket bucket = BookCommandBucket.getInstance();
|
dataWriter.addValue("data", bucket);
|
}
|
|
public void getBookCommand() {
|
String commandCode = dataReader.getString("code");
|
List<BookCommandMeta> metas = BookCommandBucket.getMeta(commandCode);
|
|
if (metas == null) {
|
logger.error("discount book command [{}] can not find: ", commandCode);
|
return;
|
}
|
|
dataWriter.addValue("data", metas);
|
}
|
|
public void write() throws Exception {
|
String commandCode = step.getStepParam();
|
|
if (Util.isEmpty(commandCode)) {
|
commandCode = step.getParam();
|
}
|
if (Util.isEmpty(commandCode)) {
|
commandCode = dataReader.getString("book_code");
|
}
|
|
List<BookCommand> bookCommands = BookCommandBucket.get(commandCode);
|
|
if (bookCommands == null || (bookCommands.isEmpty())) {
|
throw new Exception("Fee book command [{" + commandCode + "}] can not find: ");
|
}
|
|
//2. 获取维度(MdSubject)
|
for (BookCommand bookCommand: bookCommands) {
|
// 加载单据
|
String dataName = step.getDataName();
|
bookCommand.setDocument(dataName);
|
|
String filterStr = dataReader.getString("filter","");
|
filterStr = filterStr.replace(dataName, "document_detail");
|
bookCommand.setFilter(new Filter(filterStr));
|
}
|
|
//3. 账本加锁
|
lockStockBook(bookCommands);
|
|
//4. 创建流水表(FlowTable)并进行校验
|
for (BookCommand bookCommand: bookCommands) {
|
getFlowTableAndValidate(bookCommand, bookCommand.getDataSource());
|
}
|
|
//5. 根据Command和FlowTable记账
|
for (BookCommand bookCommand: bookCommands) {
|
doWriteBook(bookCommand);
|
}
|
}
|
|
private void lockStockBook(List<BookCommand> bookCommands) throws Exception {
|
for (BookCommand bookCommand: bookCommands) {
|
NamedSQL lockRebateBook = NamedSQL.getInstance("lockFeeBook");
|
lockRebateBook.setParam("documentTable", bookCommand.getDocumentTableName());
|
Filter filter = bookCommand.getFilter();
|
DataPackage document = bookCommand.getDocument();
|
filter.addAll(document.getFilter());
|
lockRebateBook.setFilter(filter);
|
SQLRunner.execSQL(lockRebateBook);
|
}
|
|
}
|
private boolean getFlowTableAndValidate(BookCommand bookCommand, DataSource dataSource) throws Exception {
|
return getFlowTableAndValidate(bookCommand);
|
}
|
|
|
private boolean getFlowTableAndValidate(BookCommand bookCommand) throws Exception {
|
boolean result = true;
|
|
//1. 根据【单据】获取记账工作表
|
Filter filter = bookCommand.getFilter();
|
DataPackage document = bookCommand.getDocument();
|
filter.addAll(document.getFilter());
|
DataObject master = document.getMasterDataObject();
|
|
//2. 获取数据
|
EntitySet entitySet = master.getBrowseEntitySet(filter);
|
|
FlowTable flowTable = bookCommand.getFlowTable();
|
flowTable.setEntitySet(entitySet);
|
return result;
|
}
|
|
public void doWriteBook(BookCommand bookCommand) throws Exception {
|
//1. 记库存流水
|
writeStockFlow(bookCommand);
|
|
//2. 记库存明细
|
writeStockDetail(bookCommand);
|
}
|
|
private void writeStockFlow(BookCommand bookCommand) throws Exception {
|
QtyCommand qtyCommand = bookCommand.getQtyCommand();
|
if (qtyCommand.isDoNothing()) {
|
return;
|
}
|
|
//1. 记录流水账
|
DataObject dataObject = DataObject.getInstance(bookCommand.getFlowTableName());
|
String batchMark = bookCommand.getBatchMark();
|
String documentDocType = bookCommand.getDocumentDocType();
|
FlowTable flowTable = bookCommand.getFlowTable();
|
|
IOnlineUser onlineUser = IOnlineUser.getInstance();
|
|
for (Entity flow : flowTable) {
|
BigDecimal qty = flow.getBigDecimal("final_amt", BigDecimal.ZERO);
|
|
if (BigDecimal.ZERO.equals(qty)) {
|
continue;
|
}
|
EntitySaver saver = dataObject.createEntitySaver();
|
|
saver.set("id", ID.newValue());
|
saver.set("doc_detail_id", flow.getId());
|
saver.set("doc_type", flow.getValue("type_code"));
|
saver.set("document_doc_type", documentDocType);
|
saver.set("config_doc_type", documentDocType);
|
saver.set("type_code", flow.getValue("type_code"));
|
saver.set("type_name", flow.getValue("type_name"));
|
|
saver.set("year", flow.getValue("year"));
|
saver.set("quarter", flow.getValue("quarter"));
|
saver.set("month", flow.getValue("month"));
|
saver.set("doc_date", flow.getValue("doc_date"));
|
saver.set("book_date", new Date());
|
saver.set("doc_code", flow.getString("code"));
|
|
saver.set("region", flow.getString("region_name"));
|
saver.set("product_name", flow.getString("product_name"));
|
saver.set("product_code", flow.getString("product_code"));
|
saver.set("product_id", flow.getString("product_id"));
|
saver.set("customer_id", flow.getValue("customer_id"));
|
saver.set("customer_code", flow.getValue("customer_code"));
|
saver.set("customer_name", flow.getValue("customer_name"));
|
saver.set("record_operator", RecordOperator.Insert);
|
saver.set("creator_id", flow.getValue("creator_id"));
|
saver.set("creator_name", flow.getValue("creator_name"));
|
|
boolean qtyChanged = false;
|
boolean negativeConver = bookCommand.isNegativeConvert();
|
|
if (qtyCommand.isSetAdd()) {
|
BigDecimal qty_add = qty.multiply(qtyCommand.getAddOperator());
|
|
if (qty_add.compareTo(BigDecimal.ZERO) < 0 && negativeConver) {
|
saver.set("num_delete", BigDecimal.ZERO.subtract(qty_add));
|
}
|
else {
|
saver.set("num_add", qty_add);
|
}
|
qtyChanged = true;
|
}
|
|
if (qtyCommand.isSetDelete()) {
|
BigDecimal qty_delete = qty.multiply(qtyCommand.getDeleteOperator());
|
|
if (qty_delete.compareTo(BigDecimal.ZERO) < 0 && negativeConver) {
|
saver.set("num_add", BigDecimal.ZERO.subtract(qty_delete));
|
}
|
else {
|
saver.set("num_delete", qty_delete);
|
}
|
|
qtyChanged = true;
|
}
|
|
FreezeCondition freezeCondition = bookCommand.getFreezeCondition();
|
|
if (qtyCommand.isSetFreeze()) {
|
BigDecimal qty_freeze = qty.multiply(qtyCommand.getFreezeOperator());
|
|
//1. 例如:库存调整单,只有调减审批的时候才需要正数记冻结,只有调减审批不通过才能用负数记冻结
|
if (freezeCondition.isCompatible(qty_freeze)) {
|
saver.set("num_freeze", qty_freeze);
|
qtyChanged = true;
|
}
|
}
|
|
if (qtyCommand.isSetUnfreeze()) {
|
BigDecimal qty_unfreeze = qty.multiply(qtyCommand.getUnfreezeOperator());
|
|
//2. 例如:库存调整单,只有调减审批通过的时候才需要减少冻结
|
if (freezeCondition.isCompatible(qty_unfreeze)) {
|
saver.set("num_unfreeze", qty_unfreeze);
|
qtyChanged = true;
|
}
|
}
|
saver.set("batch_mark", batchMark);
|
|
if(qtyChanged) {
|
saver.insert();
|
}
|
}
|
|
NamedSQL writeFeeFlowBookFields = NamedSQL.getInstance("writeFeeFlowBook");
|
writeFeeFlowBookFields.setParam("flowTable", bookCommand.getFlowTableName());
|
writeFeeFlowBookFields.setParam("bookTable", bookCommand.getDetailTableName());
|
writeFeeFlowBookFields.setParam("batch_mark", batchMark);
|
writeFeeFlowBookFields.execute();
|
}
|
|
private void writeStockDetail(BookCommand bookCommand) throws Exception {
|
BookResult result = new BookResult();
|
String batchMark = bookCommand.getBatchMark();
|
|
//1. 计入需要增加的库存明细
|
NamedSQL writeInsertStockDetail = NamedSQL.getInstance("writeInsertFeeDetail");
|
writeInsertStockDetail.setParam("batch_mark", batchMark);
|
|
try {
|
int insertCount = SQLRunner.execSQL(writeInsertStockDetail);
|
result.setInsertCount(insertCount);
|
}catch (Exception e) {
|
dataWriter.reportOneError("奖金校验", "奖金校验不通过");
|
throw new Exception("奖金校验不通过");
|
}
|
|
//2. 计入已使用
|
NamedSQL writeUpdateStockDetail = NamedSQL.getInstance("writeUpdateFeeDetail");
|
writeUpdateStockDetail.setParam("batch_mark", batchMark);
|
int updateCount = SQLRunner.execSQL(writeUpdateStockDetail);
|
result.setUpdateCount(updateCount);
|
|
//3. 补充明细账字段(余额,可用金额)
|
NamedSQL resetStockDetailOtherFields = NamedSQL.getInstance("resetFeeDetailOtherFields");
|
resetStockDetailOtherFields.setParam("batch_mark", bookCommand.getBatchMark());
|
resetStockDetailOtherFields.execute();
|
|
//4. 检查余额,可用余额
|
NamedSQL getNegativeStockDetail = NamedSQL.getInstance("getNegativeFeeDetail");
|
getNegativeStockDetail.setParam("batch_mark", batchMark);
|
int negativeCount = SQLRunner.getInteger(getNegativeStockDetail);
|
|
if (negativeCount > 0) {
|
dataWriter.reportOneError("余额校验", "余额不足,无法抵扣");
|
throw new Exception("余额不足,无法抵扣");
|
}
|
|
//4. 日志并校验
|
logger.debug("奖金明细>>计划记账{}条, 插入{} 条,修改{}条, 删除{}条;批次号:{}",
|
result.getPlanCount(), result.getInsertCount(),
|
result.getUpdateCount(), result.getDeleteCount(), batchMark);
|
|
if (!result.isValid()) {
|
}
|
}
|
|
public String tranferDocumentDocType(String docType) throws Exception {
|
DataObject dataObject = DataObject.getInstance("fee_model_project");
|
Entity entity = dataObject.getTableEntity(docType);
|
return entity.getString("name");
|
}
|
}
|