调整发票作废、发票使用功能,可以任意作废领用记录中的一张发票

dev
lisai17@sina.com 2020-10-16 00:40:25 +08:00
parent a296ab03a9
commit d4a44ec08c
9 changed files with 288 additions and 103 deletions

View File

@ -5,7 +5,7 @@ import com.jfinal.plugin.activerecord.IBean;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
/** /**
* Generated by COWR Mon Sep 21 13:04:24 CST 2020 * Generated by COWR Thu Oct 15 17:44:33 CST 2020
* TableName: invoice_receive * TableName: invoice_receive
* Remarks: - * Remarks: -
* PrimaryKey: id * PrimaryKey: id
@ -284,5 +284,27 @@ public abstract class BaseInvoiceReceive<M extends BaseInvoiceReceive<M>> extend
return getStr("invoice_number"); return getStr("invoice_number");
} }
/**
* name: invalid_count
* type: INT(10)
* isNullable: NO
* isPrimaryKey: NO
* defaultValue: 0
* @param invalidCount
*/
@JSONField(name="invalid_count")
public void setInvalidCount(Integer invalidCount) {
set("invalid_count", invalidCount);
}
/**
* @return invalid_count
*/
@JSONField(name="invalid_count")
public Integer getInvalidCount() {
return getInt("invalid_count");
}
} }

View File

@ -2,6 +2,7 @@ package com.cowr.ssjygl.invoice.log;
import com.cowr.common.Const; import com.cowr.common.Const;
import com.cowr.common.base.BaseService; import com.cowr.common.base.BaseService;
import com.cowr.common.enums.OrderStateEnum;
import com.cowr.common.utils.DataUtil; import com.cowr.common.utils.DataUtil;
import com.cowr.common.utils.DateTimeUtil; import com.cowr.common.utils.DateTimeUtil;
import com.cowr.common.view.PageParam; import com.cowr.common.view.PageParam;
@ -25,6 +26,15 @@ import java.util.List;
public class InvoiceLogService extends BaseService { public class InvoiceLogService extends BaseService {
public static final InvoiceLogService me = new InvoiceLogService(); public static final InvoiceLogService me = new InvoiceLogService();
public InvoiceLog checkInvalidInvoiceLog(String invoice_number, String invoice_code){
return InvoiceLog.dao.findFirst(
"select * from invoice_log t where t.state = ? and t.invoice_number = ? and t.code = ?",
OrderStateEnum.INVALID.getStateid(),
invoice_number,
invoice_code
);
}
public Page<Record> find(PageParam pp, String invoice_number, Integer supermarket_id, Integer state, String order_sn, String stm, String etm, String code, Integer invoice_type) { public Page<Record> find(PageParam pp, String invoice_number, Integer supermarket_id, Integer state, String order_sn, String stm, String etm, String code, Integer invoice_type) {
String selectsql = "select t.*, r.supermarket_id, s.name supermarket_name, \n" + String selectsql = "select t.*, r.supermarket_id, s.name supermarket_name, \n" +
" case when t.type = 1 then o.weight when t.type = 3 then p.weight end weight, \n" + " case when t.type = 1 then o.weight when t.type = 3 then p.weight end weight, \n" +

View File

@ -2,7 +2,9 @@ package com.cowr.ssjygl.invoice.receive;
import com.cowr.common.Const; import com.cowr.common.Const;
import com.cowr.common.base.BaseService; import com.cowr.common.base.BaseService;
import com.cowr.common.enums.OrderStateEnum;
import com.cowr.common.view.PageParam; import com.cowr.common.view.PageParam;
import com.cowr.model.InvoiceLog;
import com.cowr.model.InvoiceReceive; import com.cowr.model.InvoiceReceive;
import com.jfinal.kit.StrKit; import com.jfinal.kit.StrKit;
import com.jfinal.log.Log; import com.jfinal.log.Log;
@ -11,7 +13,9 @@ import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record; import com.jfinal.plugin.activerecord.Record;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Generated by COWR Thu Aug 13 22:45:08 CST 2020 * Generated by COWR Thu Aug 13 22:45:08 CST 2020
@ -24,23 +28,25 @@ public class InvoiceReceiveService extends BaseService {
public static final InvoiceReceiveService me = new InvoiceReceiveService(); public static final InvoiceReceiveService me = new InvoiceReceiveService();
/** /**
* *
*
* @param supermarket_id * @param supermarket_id
* @param invoice_number * @param invoice_number
* @param invoice_code * @param invoice_code
* @return * @return
*/ */
public InvoiceReceive checkReceive(int supermarket_id, String invoice_number, String invoice_code) { public InvoiceReceive checkReceive(int supermarket_id, String invoice_number, String invoice_code) {
if(!StrKit.notBlank(invoice_number, invoice_code)){ if (!StrKit.notBlank(invoice_number, invoice_code)) {
return null; return null;
} }
Long code = Long.parseLong(invoice_code); Integer code = Integer.parseInt(invoice_code);
String sql = "select cast(t.end_code as unsigned integer) - t.surplus, t.* from invoice_receive t\n" + String sql = "select * from invoice_receive t\n" +
" where t.supermarket_id = ? \n" + " where t.supermarket_id = ? \n" +
" and t.surplus > 0 \n" +
" and t.invoice_number = ? \n" + " and t.invoice_number = ? \n" +
" and t.end_code >= ? \n" + " and cast(t.start_code as unsigned integer) <= ? \n" +
" and cast(t.end_code as unsigned integer) - t.surplus < ? \n" + " and cast(t.end_code as unsigned integer) >= ? \n" +
" limit 1"; " limit 1";
InvoiceReceive receive = InvoiceReceive.dao.findFirst(sql, supermarket_id, invoice_number, code, code); InvoiceReceive receive = InvoiceReceive.dao.findFirst(sql, supermarket_id, invoice_number, code, code);
@ -48,41 +54,56 @@ public class InvoiceReceiveService extends BaseService {
return receive; return receive;
} }
/**
*
* @param supermarket_id
* @param invoice_number
* @return
*/
public InvoiceReceive foremostReceive(int supermarket_id, String invoice_number) {
String sql = "select * from invoice_receive t\n" +
" where t.supermarket_id = ? \n" +
" and t.invoice_number = ? \n" +
" and t.surplus > 0\n" +
" order by cast(t.start_code as unsigned integer) asc\n" +
" limit 1";
InvoiceReceive receive = InvoiceReceive.dao.findFirst(sql, supermarket_id, invoice_number);
return receive;
}
public String nextInvoiceCode(InvoiceReceive receive) { public String nextInvoiceCode(InvoiceReceive receive) {
if (receive == null) { if (receive == null) { // 前面判断过了,应该不会再这里出现 null
log.debug("没有有效的发票领用记录"); log.debug("没有有效的发票领用记录");
return null; return null;
} }
if (receive.getSurplus() == 0) { if (receive.getSurplus() == 0) { // 前面判断过了,应该不会再这里出现 surplus == 0
log.debug("没有可用发票"); log.debug("没有可用发票");
return null; return null;
} }
if (receive.getCurrentCode() == null) { String next_invoice_code = String.format("%0" + receive.getStartCode().length() + "d", Integer.parseInt(receive.getCurrentCode()) + 1);
return receive.getStartCode();
} else { // 按领用 id 找到所有作废的发票
return String.format("%0" + receive.getStartCode().length() + "d", Integer.parseInt(receive.getCurrentCode()) + 1); List<InvoiceLog> invoiceLogs = InvoiceLog.dao.find(
"select * from invoice_log t where t.invoice_receive_id = ? and t.state = ? ",
receive.getId(),
OrderStateEnum.INVALID.getStateid()
);
return getValidInvoiceCode(receive, next_invoice_code, invoiceLogs);
}
private String getValidInvoiceCode(InvoiceReceive receive, String next_invoice_code, List<InvoiceLog> invoiceLogs) {
for (InvoiceLog invoiceLog : invoiceLogs) {
if (invoiceLog.getCode().equals(next_invoice_code)) {
// 如果发票已作废,需要顺延
receive.setSurplus(receive.getSurplus() - 1);
if (receive.getSurplus() == 0) {
// 剩余的已经被用完了
log.debug("没有可用发票");
return null;
}
String next_next_invoice_code = String.format("%0" + receive.getStartCode().length() + "d", Integer.parseInt(next_invoice_code) + 1);
return getValidInvoiceCode(receive, next_next_invoice_code, invoiceLogs);
}
}
return next_invoice_code;
}
private String getValidInvoiceCode(String invoice_number, String next_invoice_code, Map<String, InvoiceLog> map){
if(map.containsKey(invoice_number + "_" + next_invoice_code)){ // 说明下一个发票号码已经作废,需要继续顺延
return getValidInvoiceCode(invoice_number, String.format("%0" + next_invoice_code.length() + "d", Integer.parseInt(next_invoice_code) + 1), map);
}else{
return next_invoice_code;
} }
} }
@ -93,21 +114,55 @@ public class InvoiceReceiveService extends BaseService {
* @param supermarket_id * @param supermarket_id
* @return * @return
*/ */
public List<Record> nextInvoiceCode(int supermarket_id) { public List<Record> nextInvoiceCodes(int supermarket_id) {
String sql = "select * from invoice_receive t\n" + String sql = "select * from invoice_receive t\n" +
" where t.supermarket_id = ? \n" + " where t.supermarket_id = ? \n" +
" and t.surplus > 0\n" + " and t.surplus > 0\n" +
" order by cast(t.start_code as unsigned integer) asc"; " order by cast(t.start_code as unsigned integer) asc";
List<InvoiceReceive> receives = InvoiceReceive.dao.find(sql, supermarket_id); List<InvoiceReceive> receives = InvoiceReceive.dao.find(sql, supermarket_id);
if (receives.isEmpty()) {
return new ArrayList<>();
}
List<Record> out = new ArrayList<>(); List<Record> out = new ArrayList<>();
List<Object> params = new ArrayList<>();
List<String> sqlparams = new ArrayList<>();
for (InvoiceReceive receive : receives) {
params.add(receive.getId());
sqlparams.add("?");
}
if (!sqlparams.isEmpty()) {
// 凡是有 invoice_log 记录的发票都不能再用了
List<InvoiceLog> logs = InvoiceLog.dao.find("select * from invoice_log t where t.invoice_receive_id in(" + StrKit.join(sqlparams, ",") + ")", params.toArray());
Map<String, InvoiceLog> map = new HashMap<>();
for(InvoiceLog l : logs){
map.put(l.getInvoiceNumber() + "_" + l.getCode(), l);
}
for (InvoiceReceive receive : receives) { for (InvoiceReceive receive : receives) {
Record record = receive.toRecord(); Record record = receive.toRecord();
record.set("next_invoice_code", nextInvoiceCode(receive));
String next_invoice_code = receive.getCurrentCode() == null ? receive.getStartCode() : receive.getCurrentCode();
next_invoice_code = getValidInvoiceCode(receive.getInvoiceNumber(), next_invoice_code, map);
if(Long.parseLong(next_invoice_code) > Long.parseLong(receive.getEndCode())){
log.debug("顺延后的 next_invoice_code 超过了 end_code %s %s", receive.getId(), next_invoice_code);
continue;
}
record.set("next_invoice_code", next_invoice_code);
out.add(record); out.add(record);
} }
}
return out; return out;
} }

View File

@ -66,7 +66,7 @@ public class InvoiceReceiveController extends Controller {
public void nextInvoice() { public void nextInvoice() {
Integer supermarket_id = getInt("supermarket_id", 0); Integer supermarket_id = getInt("supermarket_id", 0);
List<Record> receives = InvoiceReceiveService.me.nextInvoiceCode(supermarket_id); List<Record> receives = InvoiceReceiveService.me.nextInvoiceCodes(supermarket_id);
if (receives == null || receives.isEmpty()) { if (receives == null || receives.isEmpty()) {
renderJson(Result.failed("没有有效的发票领用记录")); renderJson(Result.failed("没有有效的发票领用记录"));
return; return;

View File

@ -91,7 +91,7 @@ public class Config extends JFinalConfig {
public static DeviceThread deviceThread = new DeviceThread(); public static DeviceThread deviceThread = new DeviceThread();
public static SocketIOService socketio = null; public static SocketIOService socketio = null;
private static boolean client_run = true; private static boolean client_run = true;
public static final String CLINET_VERSION = "20201015.1"; public static final String CLINET_VERSION = "20201016";
public static String getRootPath() { public static String getRootPath() {
return PathKit.getWebRootPath() return PathKit.getWebRootPath()

View File

@ -11,6 +11,7 @@ import com.cowr.local.ssjygl.main.CliCacheData;
import com.cowr.local.ssjygl.main.Config; import com.cowr.local.ssjygl.main.Config;
import com.cowr.local.ssjygl.order.LocalOrderService; import com.cowr.local.ssjygl.order.LocalOrderService;
import com.cowr.local.ssjygl.order.orderseq.OrderSeqService; import com.cowr.local.ssjygl.order.orderseq.OrderSeqService;
import com.cowr.ssjygl.invoice.log.InvoiceLogService;
import com.cowr.ssjygl.invoice.receive.InvoiceReceiveService; import com.cowr.ssjygl.invoice.receive.InvoiceReceiveService;
import com.cowr.ssjygl.order.ordercluster.OrderclusterService; import com.cowr.ssjygl.order.ordercluster.OrderclusterService;
import com.cowr.ssjygl.supermarket.product.SupermarketProductService; import com.cowr.ssjygl.supermarket.product.SupermarketProductService;
@ -60,6 +61,11 @@ public class OrderTempSyncService {
return Result.failed("没有有效的发票领用记录,或者发票已经被使用"); return Result.failed("没有有效的发票领用记录,或者发票已经被使用");
} }
InvoiceLog invoiceLog = InvoiceLogService.me.checkInvalidInvoiceLog(invoice_number, invoice_code);
if (invoiceLog != null) {
return Result.failedstr("发票 %s|%s 已作废", invoice_number, invoice_code);
}
Product product = Product.dao.findById(product_id); Product product = Product.dao.findById(product_id);
if (product == null) { if (product == null) {
@ -153,9 +159,18 @@ public class OrderTempSyncService {
Stock stock = Stock.dao.findByIds(transport.getSupermarketId(), order.getProductId()); Stock stock = Stock.dao.findByIds(transport.getSupermarketId(), order.getProductId());
if (stock == null) { if (stock == null) {
log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId()); log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId());
stock = new Stock();
stock.setProductId(order.getProductId());
stock.setSupermarketId(order.getSupermarketId());
stock.setStockWeight(new BigDecimal(0).subtract(net_weight));
ret = stock.save();
if (!ret) {
return false; return false;
} }
synctask.addSaveData(stock);
} else {
stock.setStockWeight(stock.getStockWeight().subtract(net_weight)); // 销售减库存 stock.setStockWeight(stock.getStockWeight().subtract(net_weight)); // 销售减库存
ret = stock.update(); ret = stock.update();
@ -163,6 +178,9 @@ public class OrderTempSyncService {
return false; return false;
} }
synctask.addUpdateData(stock);
}
// if (req_receipt == 1) { // 需要同时开具发票 // if (req_receipt == 1) { // 需要同时开具发票
// 这里的 finalReceive 在前面肯定验证过了 // 这里的 finalReceive 在前面肯定验证过了
receive.setSurplus(receive.getSurplus() - 1); receive.setSurplus(receive.getSurplus() - 1);
@ -199,7 +217,6 @@ public class OrderTempSyncService {
synctask.addUpdateData(transport); synctask.addUpdateData(transport);
synctask.addSaveData(order); synctask.addSaveData(order);
synctask.addUpdateData(stock);
return SyncTaskService.me.save(synctask); return SyncTaskService.me.save(synctask);
} catch (Exception e) { } catch (Exception e) {
@ -209,6 +226,11 @@ public class OrderTempSyncService {
} }
}); });
// 数据库保存成功后,立即推送到服务端,及时更新发票使用信息
if (ret) {
SyncTaskService.me.send(synctask);
}
// if (order.getPayType() == 1) { // if (order.getPayType() == 1) {
return LocalOrderService.me.orderPayComplete(ret, order.toRecord(), transport, printerId); return LocalOrderService.me.orderPayComplete(ret, order.toRecord(), transport, printerId);
// } else { // } else {
@ -306,9 +328,17 @@ public class OrderTempSyncService {
return Result.failed("没有有效的发票领用记录,或者发票已经被使用"); return Result.failed("没有有效的发票领用记录,或者发票已经被使用");
} }
InvoiceLog invoiceLog = InvoiceLogService.me.checkInvalidInvoiceLog(invoice_number, invoice_code);
if (invoiceLog != null) {
return Result.failedstr("发票 %s|%s 已作废", invoice_number, invoice_code);
}
order.setInvoiceCode(invoice_code); order.setInvoiceCode(invoice_code);
order.setInvoiceNumber(invoice_number); order.setInvoiceNumber(invoice_number);
receive.setSurplus(receive.getSurplus() - 1);
receive.setCurrentCode(invoice_code);
order.setInvoiceType(1); // 需要开发票的,都是冠名发票 order.setInvoiceType(1); // 需要开发票的,都是冠名发票
} else { } else {
order.setInvoiceType(2); // 不需要开发票的,都是要专票的 order.setInvoiceType(2); // 不需要开发票的,都是要专票的
@ -418,9 +448,18 @@ public class OrderTempSyncService {
Stock stock = Stock.dao.findByIds(transport.getSupermarketId(), order.getProductId()); Stock stock = Stock.dao.findByIds(transport.getSupermarketId(), order.getProductId());
if (stock == null) { if (stock == null) {
log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId()); log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId());
stock = new Stock();
stock.setProductId(order.getProductId());
stock.setSupermarketId(order.getSupermarketId());
stock.setStockWeight(new BigDecimal(0).subtract(net_weight));
ret = stock.save();
if (!ret) {
return false; return false;
} }
synctask.addSaveData(stock);
} else {
stock.setStockWeight(stock.getStockWeight().subtract(net_weight)); // 销售减库存 stock.setStockWeight(stock.getStockWeight().subtract(net_weight)); // 销售减库存
ret = stock.update(); ret = stock.update();
@ -428,11 +467,11 @@ public class OrderTempSyncService {
return false; return false;
} }
synctask.addUpdateData(stock);
}
if (ordercluster.getReqReceipt() == 1) { // 需要同时开具发票 if (ordercluster.getReqReceipt() == 1) { // 需要同时开具发票
// 这里的 finalReceive 在前面肯定验证过了 // 这里的 finalReceive 在前面肯定验证过了
finalReceive.setSurplus(finalReceive.getSurplus() - 1);
finalReceive.setCurrentCode(invoice_code);
ret = finalReceive.update(); ret = finalReceive.update();
if (!ret) { if (!ret) {
@ -465,7 +504,6 @@ public class OrderTempSyncService {
// 在这里更新sn字段之后存入 // 在这里更新sn字段之后存入
synctask.addSaveData(order); synctask.addSaveData(order);
synctask.addUpdateData(transport); synctask.addUpdateData(transport);
synctask.addUpdateData(stock);
return SyncTaskService.me.save(synctask); return SyncTaskService.me.save(synctask);
} catch (Exception e) { } catch (Exception e) {
@ -475,6 +513,11 @@ public class OrderTempSyncService {
} }
}); });
// 数据库保存成功后,立即推送到服务端,及时更新发票使用信息
if (ret) {
SyncTaskService.me.send(synctask);
}
return LocalOrderService.me.orderPayComplete(ret, order.toRecord(), transport, printerId); return LocalOrderService.me.orderPayComplete(ret, order.toRecord(), transport, printerId);
} }
@ -582,7 +625,7 @@ public class OrderTempSyncService {
// 2020-09-29 需要开具专票的,先开具结算单,不打发票 // 2020-09-29 需要开具专票的,先开具结算单,不打发票
// 2020-10-12 所有超市都可以开结算单 // 2020-10-12 所有超市都可以开结算单
if ( customer.getInvoiceType() == 2) { if (customer.getInvoiceType() == 2) {
order.setInvoiceType(2); order.setInvoiceType(2);
// 需要专票的,在结算开了专票之后,再修改 invoice_site 字段 // 需要专票的,在结算开了专票之后,再修改 invoice_site 字段
} else { } else {
@ -591,6 +634,11 @@ public class OrderTempSyncService {
return Result.failed("没有有效的发票领用记录,或者发票已经被使用"); return Result.failed("没有有效的发票领用记录,或者发票已经被使用");
} }
InvoiceLog invoiceLog = InvoiceLogService.me.checkInvalidInvoiceLog(invoice_number, invoice_code);
if (invoiceLog != null) {
return Result.failedstr("发票 %s|%s 已作废", invoice_number, invoice_code);
}
// 不满足开专票的条件的,就必须开具冠名发票 // 不满足开专票的条件的,就必须开具冠名发票
// if (req_receipt == 1) { // 需要同时开具发票 // if (req_receipt == 1) { // 需要同时开具发票
order.setInvoiceCode(invoice_code); order.setInvoiceCode(invoice_code);
@ -732,9 +780,18 @@ public class OrderTempSyncService {
Stock stock = Stock.dao.findByIds(transport.getSupermarketId(), order.getProductId()); Stock stock = Stock.dao.findByIds(transport.getSupermarketId(), order.getProductId());
if (stock == null) { if (stock == null) {
log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId()); log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId());
stock = new Stock();
stock.setProductId(order.getProductId());
stock.setSupermarketId(order.getSupermarketId());
stock.setStockWeight(new BigDecimal(0).subtract(net_weight));
ret = stock.save();
if (!ret) {
return false; return false;
} }
synctask.addSaveData(stock);
} else {
stock.setStockWeight(stock.getStockWeight().subtract(net_weight)); // 销售减库存 stock.setStockWeight(stock.getStockWeight().subtract(net_weight)); // 销售减库存
ret = stock.update(); ret = stock.update();
@ -742,6 +799,9 @@ public class OrderTempSyncService {
return false; return false;
} }
synctask.addUpdateData(stock);
}
if (finalReceive != null) { if (finalReceive != null) {
// if (req_receipt == 1) { // 需要同时开具发票 // if (req_receipt == 1) { // 需要同时开具发票
// 这里的 finalReceive 在前面肯定验证过了 // 这里的 finalReceive 在前面肯定验证过了
@ -781,7 +841,6 @@ public class OrderTempSyncService {
// 在这里更新sn字段之后存入 // 在这里更新sn字段之后存入
synctask.addSaveData(order); synctask.addSaveData(order);
synctask.addUpdateData(transport); synctask.addUpdateData(transport);
synctask.addUpdateData(stock);
return SyncTaskService.me.save(synctask); return SyncTaskService.me.save(synctask);
} catch (Exception e) { } catch (Exception e) {
@ -791,7 +850,7 @@ public class OrderTempSyncService {
} }
}); });
// 数据库修改成功后,再将数据下发 // 数据库保存成功后,立即推送到服务端,及时更新各个地方的客户余额
if (ret) { if (ret) {
SyncTaskService.me.send(synctask); SyncTaskService.me.send(synctask);
} }
@ -929,13 +988,27 @@ public class OrderTempSyncService {
Stock stock = Stock.dao.findByIds(order.getSupermarketId(), order.getProductId()); Stock stock = Stock.dao.findByIds(order.getSupermarketId(), order.getProductId());
if (stock == null) { if (stock == null) {
log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId()); log.error("未找到库存信息 %s, %s", order.getSupermarketId(), order.getProductId());
stock = new Stock();
stock.setProductId(order.getProductId());
stock.setSupermarketId(order.getSupermarketId());
stock.setStockWeight(order.getWeight());
ret = stock.save();
if (!ret) {
return false;
}
synctask.addSaveData(stock);
} else {
stock.setStockWeight(order.getWeight()); // 销售减库存
ret = stock.update();
if (!ret) {
return false; return false;
} }
stock.setStockWeight(stock.getStockWeight().add(order.getWeight())); // 取消销售加库存
ret = stock.update();
synctask.addUpdateData(stock); synctask.addUpdateData(stock);
}
return ret && SyncTaskService.me.save(synctask) return ret && SyncTaskService.me.save(synctask)
&& ModifyLogSyncService.me.save(order.tablename, "sn", logrecord.toJson(), Enums.DataOpType.UPDATE.getId(), sysuser); && ModifyLogSyncService.me.save(order.tablename, "sn", logrecord.toJson(), Enums.DataOpType.UPDATE.getId(), sysuser);
@ -964,22 +1037,32 @@ public class OrderTempSyncService {
return Result.failed("订单已经取消"); return Result.failed("订单已经取消");
} }
if (StrKit.notBlank(order.getInvoiceCode())) {
return Result.failedstr("请先将已开具的发票[%s]取消", order.getInvoiceCode());
}
InvoiceReceive receive = InvoiceReceiveService.me.checkReceive(order.getSupermarketId(), invoice_number, invoice_code); InvoiceReceive receive = InvoiceReceiveService.me.checkReceive(order.getSupermarketId(), invoice_number, invoice_code);
if (receive == null) { if (receive == null) {
return Result.failed("没有有效的发票领用记录,或者发票已经被使用"); return Result.failed("没有有效的发票领用记录,或者发票已经被使用");
} }
if (StrKit.notBlank(order.getInvoiceCode())) { InvoiceLog invoiceLog = InvoiceLogService.me.checkInvalidInvoiceLog(invoice_number, invoice_code);
return Result.failedstr("请先将已开具的发票[%s]取消", order.getInvoiceCode()); if (invoiceLog != null) {
return Result.failedstr("发票 %s|%s 已作废", invoice_number, invoice_code);
} }
order.setInvoiceCode(invoice_code); order.setInvoiceCode(invoice_code);
order.setInvoiceNumber(invoice_number); order.setInvoiceNumber(invoice_number);
receive.setSurplus(receive.getSurplus() - 1);
receive.setCurrentCode(invoice_code);
Record logrecord = new Record(); Record logrecord = new Record();
logrecord.set("sn", sn); logrecord.set("sn", sn);
logrecord.set("invoice", invoice_code); logrecord.set("invoice", invoice_code);
SyncTask synctask = new SyncTask();
boolean ret = Db.tx(new IAtom() { boolean ret = Db.tx(new IAtom() {
@Override @Override
public boolean run() { public boolean run() {
@ -990,9 +1073,6 @@ public class OrderTempSyncService {
return false; return false;
} }
receive.setSurplus(receive.getSurplus() - 1);
receive.setCurrentCode(invoice_code);
ret = receive.update(); ret = receive.update();
if (!ret) { if (!ret) {
@ -1018,8 +1098,6 @@ public class OrderTempSyncService {
return false; return false;
} }
SyncTask synctask = new SyncTask();
synctask.addUpdateData(order); synctask.addUpdateData(order);
synctask.addSaveData(invoiceLog); synctask.addSaveData(invoiceLog);
synctask.addUpdateData(receive); synctask.addUpdateData(receive);
@ -1034,6 +1112,9 @@ public class OrderTempSyncService {
}); });
if (ret) { if (ret) {
// 数据库保存成功后,立即推送到服务端,及时更新发票使用信息
SyncTaskService.me.send(synctask);
Transport transport = Transport.dao.findById(order.get("transport_id")); Transport transport = Transport.dao.findById(order.get("transport_id"));
if (transport == null) { if (transport == null) {

View File

@ -122,7 +122,11 @@ public class TransportQueryService {
} }
// transobj.set("next_invoice_code", InvoiceReceiveService.me.nextInvoiceCode(transport.getSupermarketId())); // 2020-09-21 加了发票代码 // transobj.set("next_invoice_code", InvoiceReceiveService.me.nextInvoiceCode(transport.getSupermarketId())); // 2020-09-21 加了发票代码
transobj.set("invoice_numbers", InvoiceReceiveService.me.nextInvoiceCode(transport.getSupermarketId())); // TODO 专票? if(ordercluster.getReqReceipt() == 1){ // 需要打印发票的,才去插领票记录
transobj.set("invoice_numbers", InvoiceReceiveService.me.nextInvoiceCodes(transport.getSupermarketId()));
}else{
transobj.set("invoice_numbers", new ArrayList<>());
}
transobj.set("req_receipt", ordercluster.getReqReceipt()); // TODO 2020-10-12 如果放开购买,连零散购砂都不做配额了,这里需要修改 transobj.set("req_receipt", ordercluster.getReqReceipt()); // TODO 2020-10-12 如果放开购买,连零散购砂都不做配额了,这里需要修改
return Result.success(transobj); return Result.success(transobj);

View File

@ -141,25 +141,26 @@ public class InvoiceLogSyncService extends BaseSyncService {
return Result.failed("未找到超市信息"); return Result.failed("未找到超市信息");
} }
InvoiceLog invoiceLog = InvoiceLog.dao.findFirst("select * from invoice_log t where code = ? limit 1 ", code); // 先判断这张发票有没有被领用
InvoiceReceive receive = InvoiceReceiveService.me.checkReceive(supermarket_id, invoice_number, code);
if (receive == null) {
return Result.failed("没有有效的发票领用记录,或者发票已经被使用");
}
InvoiceLog invoiceLog = InvoiceLog.dao.findFirst("select * from invoice_log t \n" +
" where t.invoice_number = ? and t.code = ? limit 1 ", invoice_number, code);
if (invoiceLog != null) { if (invoiceLog != null) {
// 再判断这张发票是不是已经被取消了
if (invoiceLog.getState() == OrderStateEnum.INVALID.getStateid()) {
return Result.failed("发票已作废");
} else {
// 还要判断这张发票已经在订单上使用了
return Result.failed("发票已使用,请使用“取消发票”功能"); return Result.failed("发票已使用,请使用“取消发票”功能");
} }
InvoiceReceive receive = InvoiceReceiveService.me.foremostReceive(supermarket_id, invoice_number);
if (receive == null) {
return Result.failed("没有有效的发票领用记录");
} }
String next_invoice_code = InvoiceReceiveService.me.nextInvoiceCode(receive); // 然后就可以开始取消了
if (next_invoice_code == null) {
return Result.failed("没有可用发票");
}
if (!next_invoice_code.equals(code)) {
return Result.failed("只能按顺序作废发票");
}
invoiceLog = new InvoiceLog(); invoiceLog = new InvoiceLog();
invoiceLog.setId(StrKit.getRandomUUID()); invoiceLog.setId(StrKit.getRandomUUID());
@ -172,12 +173,28 @@ public class InvoiceLogSyncService extends BaseSyncService {
invoiceLog.setCode(code); invoiceLog.setCode(code);
invoiceLog.setInvoiceNumber(invoice_number); invoiceLog.setInvoiceNumber(invoice_number);
receive.setSurplus(receive.getSurplus() - 1);
receive.setInvalidCount(receive.getInvalidCount() + 1);
if (receive.getSurplus() == 0) {
// 作废最后一张发票,当前发票停再最后一个发票号码上
receive.setCurrentCode(receive.getEndCode());
} else {
if (code.equals(receive.getStartCode())) { // 作废第一张发票
receive.setCurrentCode(String.format("%0" + receive.getStartCode().length() + "d", Integer.parseInt(receive.getStartCode()) + 1));
} else if (code.equals(receive.getCurrentCode())) { // 作废顺延的下一张发票
receive.setCurrentCode(String.format("%0" + receive.getStartCode().length() + "d", Integer.parseInt(receive.getCurrentCode()) + 1));
} else {
// 其他情况下不更新 current_code
}
}
SyncTask synctask = new SyncTask(); SyncTask synctask = new SyncTask();
InvoiceLog finalInvoiceLog = invoiceLog; InvoiceLog finalInvoiceLog = invoiceLog;
boolean ret = Db.tx(new IAtom() { boolean ret = Db.tx(new IAtom() {
@Override @Override
public boolean run() throws SQLException { public boolean run() {
try { try {
boolean ret = finalInvoiceLog.save(); boolean ret = finalInvoiceLog.save();
@ -187,13 +204,9 @@ public class InvoiceLogSyncService extends BaseSyncService {
synctask.addSaveData(finalInvoiceLog); synctask.addSaveData(finalInvoiceLog);
receive.setSurplus(receive.getSurplus() - 1);
receive.setCurrentCode(next_invoice_code);
ret = receive.update(); ret = receive.update();
if (!ret) { if (!ret) {
log.error("发票领用信息更新失败", next_invoice_code);
return false; return false;
} }
@ -209,7 +222,7 @@ public class InvoiceLogSyncService extends BaseSyncService {
}); });
// 普票作废理解同步到砂站 // 普票作废理解同步到砂站
if(ret){ if (ret) {
SyncTaskService.me.send(synctask); SyncTaskService.me.send(synctask);
} }
@ -304,7 +317,7 @@ public class InvoiceLogSyncService extends BaseSyncService {
}); });
// 普票作废理解同步到砂站 // 普票作废理解同步到砂站
if(ret){ if (ret) {
SyncTaskService.me.send(synctask); SyncTaskService.me.send(synctask);
} }

View File

@ -133,7 +133,7 @@ public class InvoiceReceiveController extends Controller {
public void nextInvoice() { public void nextInvoice() {
Integer supermarket_id = getInt("supermarket_id", 0); Integer supermarket_id = getInt("supermarket_id", 0);
List<Record> receives = InvoiceReceiveService.me.nextInvoiceCode(supermarket_id); List<Record> receives = InvoiceReceiveService.me.nextInvoiceCodes(supermarket_id);
if (receives == null || receives.isEmpty()) { if (receives == null || receives.isEmpty()) {
renderJson(Result.failed("没有有效的发票领用记录")); renderJson(Result.failed("没有有效的发票领用记录"));
return; return;