发票识别验真

This commit is contained in:
zengweihai 2024-10-18 15:04:23 +08:00
parent eb3636588b
commit 7842e9faa6
1 changed files with 254 additions and 97 deletions

View File

@ -17,21 +17,29 @@ import kd.bos.coderule.api.CodeRuleInfo;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.datamodel.ListSelectedRowCollection;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.fileservice.FileItem;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.form.CloseCallBack;
import kd.bos.form.ShowType;
import kd.bos.form.*;
import kd.bos.form.control.AttachmentPanel;
import kd.bos.form.control.Control;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.control.events.AttachmentDownloadListener;
import kd.bos.form.control.events.UploadEvent;
import kd.bos.form.control.events.UploadListener;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.events.BeforeDoOperationEventArgs;
import kd.bos.form.events.ClientCallBackEvent;
import kd.bos.form.events.ClosedCallBackEvent;
import kd.bos.form.operate.FormOperate;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.imageplatform.axis.IScanWebServiceImplServiceStub;
import kd.bos.list.ListShowParameter;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
@ -41,6 +49,7 @@ import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.DeleteServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.url.UrlService;
@ -63,16 +72,83 @@ import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;
/**
* 付款申请单 || 费用登记单 插件
* 发票识别,发票验真验重
* qeug_recon_payreqbill_ext && qeug_recon_connotextb_ext
*/
public class ReconPayreqFormPlugin extends AbstractFormPlugin {
public class ReconPayreqFormPlugin extends AbstractFormPlugin implements UploadListener {
private static final Log logger = LogFactory.getLog(OAUtils.class);
List<String> fileExtendList = new ArrayList<String>(Arrays.asList("png","jpg","jpeg","ofd","pdf","xml"));//发票文件后缀集合
@Override
public void registerListener(EventObject e) {
super.registerListener(e);
AttachmentPanel attachmentPanel = getControl("qeug_attachmentpanelap");
attachmentPanel.addUploadListener(this);
}
/**
* 加载页面时
* @param e
*/
@Override
public void afterBindData(EventObject e) {
super.afterBindData(e);
FormShowParameter formShowParameter = this.getView().getFormShowParameter();
if(null!=formShowParameter){
Map<String, Object> customParams = formShowParameter.getCustomParams();
if(null != customParams){
Object isTicket = customParams.get("isticket");
String billstatus = this.getModel().getDataEntity().getString("billstatus");
if ("C".equals(billstatus)){
if (isTicket == null){
//附件面板锁定
this.getView().setEnable(false,"qeug_attachmentpanelap");
//发票类工具栏按钮隐藏
this.getView().setVisible(false,"advcontoolbarap2");
//分录申请核销金额锁定
this.getView().setVisible(false,"inventry_haswriteoffamt");
//设置置顶按钮隐藏
this.getView().setVisible(false,"qeug_confirmchange");
}else {
//设置置顶按钮隐藏
this.getView().setVisible(false,"bar_audit","bar_print","viewflowchart","payreqsplit","qeug_syncbip","payreqsplitsave");
}
}
}
}
}
/**
* 值更新事件:
* 1当发票附件发生变化时触发保存
* @param e
*/
@Override
public void propertyChanged(PropertyChangedArgs e) {
super.propertyChanged(e);
String name = e.getProperty().getName();
if ("qeug_attachmentcount".equals(name)){
this.getView().addClientCallBack("auto_save",0);
}
}
@Override
public void clientCallBack(ClientCallBackEvent e) {
super.clientCallBack(e);
String name = e.getName();
if ("auto_save".equals(name)){
this.getView().invokeOperation("save");
}
}
@Override
public void afterDoOperation(AfterDoOperationEventArgs args) {
super.afterDoOperation(args);
@ -96,37 +172,10 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
this.getView().showTipNotification("请先上传发票附件");
return;
}
// ToDo: 获取token
// ToDo: 获取token;重新识别无需对现存的发票的数据操作直接提示接口信息
String oaToken = getOaToken();
//发票信息分录
DynamicObjectCollection invoiceentry = this.getView().getModel().getEntryEntity("invoiceentry");
if (invoiceentry.size() > 0) {
for (DynamicObject invoice : invoiceentry) {
String qeug_invoiceno = invoice.getString("qeug_invoiceno");//分录中的发票号码
String qeug_invoicekey = invoice.getString("qeug_invoicekey");//分录中的发票保存key
Map<String, Object> map = new HashMap<>();
// 创建一个数组并将其作为值放入Map中
map.put("pi_keys", Arrays.asList(qeug_invoicekey));
ObjectMapper objectMapper = new ObjectMapper();
try {
String jsonString = objectMapper.writeValueAsString(map);
deleteInvoice(jsonString,oaToken);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
QFilter q = new QFilter("invoiceno", QCP.equals, qeug_invoiceno);
DynamicObject recon_invoicebill = BusinessDataServiceHelper.loadSingle("recon_invoicebill", new QFilter[]{q});
if (null != recon_invoicebill) {
int recon_invoicebill1 = DeleteServiceHelper.delete("recon_invoicebill", new QFilter[]{q});
//失败
if (1 != recon_invoicebill1) {
this.getView().showTipNotification("删除失败:请检查发票登记单的单据状态");
}
}
}
invoiceentry.clear();
}
if(!Strings.isEmpty(oaToken)){//判断是否获取到token
for (int i = 0; i < attachments.size(); i++) {
Map<String, Object> attachment = attachments.get(i);
@ -261,10 +310,18 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
if (null != org) {
recon_invoicebill.set("org",org);
}
recon_invoicebill.set("contractbill",dataEntity.getDynamicObject("contractbill"));
recon_invoicebill.set("biztype","CONTRACT");//发票所属业务
DynamicObject project = dataEntity.getDynamicObject("project");
recon_invoicebill.set("project",project);//设置项目名称
switch (billtype){
case "recon_payreqbill"://付款申请
recon_invoicebill.set("biztype","CONTRACT");//发票所属业务为合同
recon_invoicebill.set("contractbill",dataEntity.getDynamicObject("contractbill"));//合同
break;
case "recon_connotextbill":
recon_invoicebill.set("biztype","CONNOTEXT");//发票所属业务为费用
recon_invoicebill.set("connotextbill",this.getModel().getDataEntity());//发票登记
break;
}
recon_invoicebill.set("collectionway","NORMAL");//设置征收方式为默认普通征税
if ("0".equals(invoiceState)){
recon_invoicebill.set("invoicetype","posinvoice"); //设置为正数发票
@ -299,10 +356,9 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
//todo:若接口返回汇总
//发票_明细
//todo:若接口返回明细--遍历新增发票明细分录
DynamicObjectCollection invoiceentrs = recon_invoicebill.getDynamicObjectCollection("invoiceentry");
invoiceentrs.clear();
if (items != null){
for (int x = 0; x < items.size(); x++ ){
JSONObject item = items.getJSONObject(x);
@ -331,10 +387,9 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
invoiceentr.set("entry_content",description);//项目名称
invoiceentr.set("entry_notaxamt",qeug_amount);
}
//todo:若接口返回明细--遍历新增发票明细分录
Object[] save = SaveServiceHelper.save(new DynamicObject[]{recon_invoicebill});
OperationServiceHelper.executeOperate("save","recon_invoicebill",new DynamicObject[]{recon_invoicebill});
OperationServiceHelper.executeOperate("submit","recon_invoicebill",new DynamicObject[]{recon_invoicebill});
OperationServiceHelper.executeOperate("audit","recon_invoicebill",new DynamicObject[]{recon_invoicebill});
//todo:添加发票信息分录
DynamicObject dynamicObject = invoiceentry.addNew();//新增分录行
//todo:模仿标品新增字段,为接口返回数据反写分录做准备
@ -345,6 +400,7 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
dynamicObject.set("qeug_textfield", "发票识别:"+name);
this.getView().updateView("invoiceentry");
this.getView().showSuccessNotification("发票识别成功");
refreshInvoiceEntry();
SaveServiceHelper.save(new DynamicObject[]{this.getView().getModel().getDataEntity()});
}
}else {//
@ -360,7 +416,7 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
}
}
}
this.getView().updateView("invoiceentry");
this.getView().updateView();
}else {
this.getView().showTipNotification("请先选择用款单位!");
}
@ -368,38 +424,122 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
break;
//发票验真验重
case "qeug_invoicecheck":
//todo: 发票验真验重接口
// 根据接口情况打包分录数据去OA验真验重---遍历调取接口还是汇总集合调取接口
//发票信息分录
DynamicObjectCollection invoiceens = this.getView().getModel().getEntryEntity("invoiceentry");
if (invoiceens.size() == 0) {
this.getView().showTipNotification("请先进行发票识别后,再进行验真验重");
return;
}
boolean bb = true;
//成功--新增分录行
if (bb) {
this.getView().showSuccessNotification("发票验真验重接口");
//验真验重接口调通--生成发票登记单据(recon_invoicebill)
//todo 遍历发票信息明细,批量生成发票登记单(再次点击发票验真验重,只选择未完成验真验重的数据)
}else {
//失败--提示失败信息
this.getView().showTipNotification("发票验真验重失败:请检查发票明细信息是否正确");
}
break;
case "deleteinvoiceentry":
//付款申请单发票信息明细删除行后进行保存
SaveServiceHelper.save(new DynamicObject[]{this.getView().getModel().getDataEntity()});
this.getView().showSuccessNotification("同步删除发票登记成功");
break;
default:
case "qeug_refinvoice":
//todo: 关联发票二开接口
switch (billtype){
case "recon_payreqbill"://当单据为付款申请时
DynamicObject contractbill = this.getModel().getDataEntity().getDynamicObject("contractbill");
if (contractbill != null){
ListShowParameter listShowParameter = ShowFormHelper.createShowListForm("recon_invoicebill_f7", true);
listShowParameter.setFormId("bos_listf7");
listShowParameter.setCaption(ResManager.loadKDString("请选择关联发票", "RePayReqBillFormPlugin_4", "repc-recon-formplugin"));
DynamicObjectCollection invoiceEntries = dataEntity.getDynamicObjectCollection("invoiceentry");
List<Object> selectInvoiceIds = invoiceEntries.stream().filter(invoiceEntry -> null != invoiceEntry.get("inventry_invoicebill")).map(invoiceEntry -> {
DynamicObject invoiceF7 = invoiceEntry.getDynamicObject("inventry_invoicebill");
return invoiceF7.getPkValue();
}).collect(Collectors.toList());
listShowParameter.setSelectedRows(selectInvoiceIds.toArray());
StyleCss inlineStyleCss = new StyleCss();
inlineStyleCss.setHeight("600");
inlineStyleCss.setWidth("800");
List<QFilter> qFilters = listShowParameter.getListFilterParameter().getQFilters();
qFilters.add(new QFilter("org", QCP.equals, this.getModel().getDataEntity().getDynamicObject("org").getPkValue()));
qFilters.add(new QFilter("hasredoff", QCP.equals, false));
qFilters.add(new QFilter("invoicetype", QCP.not_equals, "roffinvoice"));
qFilters.add(new QFilter("billstatus", QCP.equals, "C"));
qFilters.add(new QFilter("writeoffamount",QCP.large_than,BigDecimal.ZERO));
qFilters.add(new QFilter("contractbill.id",QCP.equals,contractbill.getPkValue()));
listShowParameter.getOpenStyle().setInlineStyleCss(inlineStyleCss);
listShowParameter.getOpenStyle().setShowType(ShowType.Modal);
listShowParameter.setCloseCallBack(new CloseCallBack(this, "recon_invoicebill_f7"));
getView().showForm(listShowParameter);
}else {
this.getView().showTipNotification("请先选择合同");
}
break;
case "recon_connotextbill"://费用登记
DynamicObject project = this.getModel().getDataEntity().getDynamicObject("project");
if (project != null){
ListShowParameter listShowParameter = ShowFormHelper.createShowListForm("recon_invoicebill_f7", true);
listShowParameter.setFormId("bos_listf7");
listShowParameter.setCaption(ResManager.loadKDString("请选择关联发票", "RePayReqBillFormPlugin_4", "repc-recon-formplugin"));
DynamicObjectCollection invoiceEntries = dataEntity.getDynamicObjectCollection("invoiceentry");
List<Object> selectInvoiceIds = invoiceEntries.stream().filter(invoiceEntry -> null != invoiceEntry.get("inventry_invoicebill")).map(invoiceEntry -> {
DynamicObject invoiceF7 = invoiceEntry.getDynamicObject("inventry_invoicebill");
return invoiceF7.getPkValue();
}).collect(Collectors.toList());
listShowParameter.setSelectedRows(selectInvoiceIds.toArray());
StyleCss inlineStyleCss = new StyleCss();
inlineStyleCss.setHeight("600");
inlineStyleCss.setWidth("800");
List<QFilter> qFilters = listShowParameter.getListFilterParameter().getQFilters();
qFilters.add(new QFilter("org", QCP.equals, this.getModel().getDataEntity().getDynamicObject("org").getPkValue()));
qFilters.add(new QFilter("hasredoff", QCP.equals, false));
qFilters.add(new QFilter("invoicetype", QCP.not_equals, "roffinvoice"));
qFilters.add(new QFilter("billstatus", QCP.equals, "C"));
qFilters.add(new QFilter("writeoffamount",QCP.large_than,BigDecimal.ZERO));
qFilters.add(new QFilter("project.id",QCP.equals,project.getPkValue()));
listShowParameter.getOpenStyle().setInlineStyleCss(inlineStyleCss);
listShowParameter.getOpenStyle().setShowType(ShowType.Modal);
listShowParameter.setCloseCallBack(new CloseCallBack(this, "recon_invoicebill_f7"));
getView().showForm(listShowParameter);
}else {
this.getView().showTipNotification("请先选择项目");
}
break;
}
break;
case "deleteinvoiceentry"://删行后自动保存
// refreshInvoiceEntry();
SaveServiceHelper.save(new DynamicObject[]{this.getModel().getDataEntity(true)});
break;
}
}
@Override
public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
super.closedCallBack(closedCallBackEvent);
DynamicObject model = getModel().getDataEntity(true);
String actionId = closedCallBackEvent.getActionId();
// 关联发票
if ("recon_invoicebill_f7".equals(actionId)) {
ListSelectedRowCollection returnData = (ListSelectedRowCollection) closedCallBackEvent.getReturnData();
if (returnData == null || returnData.isEmpty()) {
return;
}
Object[] primaryKeyValues = returnData.getPrimaryKeyValues();
DynamicObjectCollection invoiceEntries = model.getDynamicObjectCollection("invoiceentry");
List<Long> invoiceIdList = invoiceEntries.stream()
.filter(e -> null != e.get("inventry_invoicebill"))
.map(e -> e.getDynamicObject("inventry_invoicebill").getLong("id"))
.collect(Collectors.toList());
DynamicObject[] invoiceF7s = BusinessDataServiceHelper.load(primaryKeyValues,
EntityMetadataCache.getDataEntityType("recon_invoicebill_f7"));
BigDecimal invoiceAmt = BigDecimal.ZERO;
for (int i = 0; i < invoiceF7s.length; i++) {
DynamicObject invoiceBill = invoiceF7s[i];
if (invoiceIdList.contains(invoiceBill.getLong("id"))) {
continue;
}
DynamicObject invoiceEntry = invoiceEntries.addNew();
invoiceEntry.getDataEntityState().setFromDatabase(true);
invoiceEntry.set("inventry_invoicebill", invoiceBill);
invoiceEntry.set("inventry_haswriteoffamt", invoiceBill.getBigDecimal("writeoffamount"));
invoiceAmt = invoiceAmt.add(invoiceBill.getBigDecimal("invoiceamount"));
}
getModel().updateCache();
getView().updateView("invoiceentry");
refreshInvoiceEntry();
}
}
@Override
public void beforeDoOperation(BeforeDoOperationEventArgs args) {
super.beforeDoOperation(args);
@ -407,7 +547,7 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
FormOperate source = (FormOperate) args.getSource();
String operateKey = source.getOperateKey();
switch (operateKey) {
//发票识别
//删行
case "deleteinvoiceentry":
//用户在删除发票明细时如果当前发票已经生成发票登记单一并删除掉
//删除后--未保存前,遍历发票信息分录 删除满足(明细"发票号码" == 发票登记单头"发票号码")的发票登记单
@ -420,40 +560,39 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
for (int i = 0; i < selectRows.length; i++) {
int selectRow = selectRows[i];
String qeug_invoicekey = (String)this.getModel().getValue("qeug_invoicekey",selectRow);//分录中的发票保存key
noList.add(qeug_invoicekey);
}
map.put("pi_keys", noList);
String keys_str = "";
ObjectMapper objectMapper = new ObjectMapper();
try {
keys_str = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
if(!Strings.isEmpty(qeug_invoicekey)){//key不为空或者不为""
noList.add(qeug_invoicekey);
}
}
if (noList.size() > 0){
map.put("pi_keys", noList);
String keys_str = "";
ObjectMapper objectMapper = new ObjectMapper();
try {
keys_str = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
String oaToken = this.getOaToken();
JSONObject deleteResult = deleteInvoice(keys_str, oaToken);
String del_result = deleteResult.getString("success");
if ("true".equals(del_result)){
for (int i = 0; i < selectRows.length; i++) {
int selectRow = selectRows[i];
String qeug_invoiceno = (String)this.getModel().getValue("qeug_invoiceno",selectRow);//分录中的发票号码
QFilter q = new QFilter("invoiceno", QCP.equals, qeug_invoiceno);
DynamicObject recon_invoicebill = BusinessDataServiceHelper.loadSingle("recon_invoicebill", new QFilter[]{q});
if (null != recon_invoicebill) {
int recon_invoicebill1 = DeleteServiceHelper.delete("recon_invoicebill", new QFilter[]{q});
//失败
if (1 != recon_invoicebill1) {
this.getView().showTipNotification("删除失败:请检查发票登记单的单据状态");
args.setCancel(true);
return;
String oaToken = this.getOaToken();
JSONObject deleteResult = deleteInvoice(keys_str, oaToken);
String del_result = deleteResult.getString("success");
if ("true".equals(del_result)){
for (int i = 0; i < selectRows.length; i++) {
int selectRow = selectRows[i];
String qeug_invoiceno = (String)this.getModel().getValue("qeug_invoiceno",selectRow);//分录中的发票号码
QFilter q = new QFilter("invoiceno", QCP.equals, qeug_invoiceno);
DynamicObject recon_invoicebill = BusinessDataServiceHelper.loadSingle("recon_invoicebill", new QFilter[]{q});
if (null != recon_invoicebill) {
int recon_invoicebill1 = DeleteServiceHelper.delete("recon_invoicebill", new QFilter[]{q});
}
}
}else {
args.setCancel(true);//取消操作
this.getView().showTipNotification("oa删除接口调用失败"+deleteResult.getString("message"));
}
}else {
args.setCancel(true);//取消操作
this.getView().showTipNotification("oa删除接口调用失败"+deleteResult.getString("message"));
}
}
break;
default:
@ -461,6 +600,24 @@ public class ReconPayreqFormPlugin extends AbstractFormPlugin {
}
}
public void refreshInvoiceEntry() {
String billtype =this.getModel().getDataEntityType().getName();
if ("recon_payreqbill".equals(billtype)){
DynamicObjectCollection invoiceEntrys = getModel().getEntryEntity("invoiceentry");
// 记录累计发票金额
BigDecimal invoiceAmt = BigDecimal.ZERO;
// 获取数据
for(DynamicObject invoiceEntry : invoiceEntrys) {
DynamicObject invoiceBill = invoiceEntry.getDynamicObject("inventry_invoicebill");
if(null == invoiceBill) {
continue;
}
invoiceAmt = invoiceAmt.add(invoiceBill.getBigDecimal("invoiceamount"));
}
getModel().setValue("invoiceamt", invoiceAmt);//本次发票金额赋值
}
}
public String getOaToken(){
String userName = "lexmiscivrest";
String password = "lexmisciv2019";