1471 lines
61 KiB
C#
1471 lines
61 KiB
C#
using Education.Forms.領據系統;
|
|
using Education.Report;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Data.Common;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Web;
|
|
using System.Web.Script.Services;
|
|
using System.Web.Services;
|
|
using WebLib;
|
|
|
|
namespace Education.Services
|
|
{
|
|
[WebService(Namespace = "http://tempuri.org/")]
|
|
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
|
|
[System.ComponentModel.ToolboxItem(false)]
|
|
[ScriptService]
|
|
public class 領據處理 : ServiceBase
|
|
{
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse SelectPage(
|
|
int pageIndex = 1,
|
|
int pageSize = 20,
|
|
DateTime? 活動日期_1 = null,
|
|
DateTime? 活動日期_2 = null,
|
|
string 身分別 = null,
|
|
string 講師_非講師編號 = null,
|
|
string 憑證類別 = null,
|
|
string 計畫代號 = null,
|
|
string 計畫名稱 = null,
|
|
string 活動類別 = null,
|
|
string 付款方式 = null,
|
|
string 領款人姓名 = null,
|
|
string orderBy = "")
|
|
{
|
|
try
|
|
{
|
|
DAC_領據 dac = new DAC_領據();
|
|
int startRowIndex = (pageIndex - 1) * pageSize;
|
|
|
|
var data = dac.SelectPageWithRelations(
|
|
noInputReturnAll: true,
|
|
startRowIndex: startRowIndex,
|
|
maximumRows: pageSize,
|
|
活動日期_1: 活動日期_1,
|
|
活動日期_2: 活動日期_2,
|
|
身分別: 身分別,
|
|
講師_非講師編號: 講師_非講師編號,
|
|
憑證類別: 憑證類別,
|
|
計畫代號: 計畫代號,
|
|
計畫名稱: 計畫名稱,
|
|
活動類別: 活動類別,
|
|
付款方式: 付款方式,
|
|
領款人姓名: 領款人姓名,
|
|
orderBy: orderBy
|
|
);
|
|
|
|
int totalCount = dac.SelectCount(
|
|
noInputReturnAll: true,
|
|
活動日期_1: 活動日期_1,
|
|
活動日期_2: 活動日期_2,
|
|
身分別: 身分別,
|
|
講師_非講師編號: 講師_非講師編號,
|
|
憑證類別: 憑證類別,
|
|
計畫代號: 計畫代號,
|
|
計畫名稱: 計畫名稱,
|
|
活動類別: 活動類別,
|
|
付款方式: 付款方式,
|
|
領款人姓名: 領款人姓名
|
|
);
|
|
|
|
return ServiceResponse.CreateSuccess("查詢成功", data, totalCount);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"查詢失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse GetOne(int no)
|
|
{
|
|
try
|
|
{
|
|
using (var conn = DAC.NewConnection()) {
|
|
DAC_領據 dacMain = new DAC_領據(conn);
|
|
DAC_勞務費 dacLabor = new DAC_勞務費(conn);
|
|
DAC_差旅費 dacTravel = new DAC_差旅費(conn);
|
|
DAC_BPSN dacBPSN = new DAC_BPSN(conn);
|
|
|
|
var mainRec = dacMain.SelectOne(no).FirstOrDefault();
|
|
|
|
if (mainRec == null) {
|
|
return ServiceResponse.CreateError("沒有此筆資料");
|
|
}
|
|
|
|
mainRec.DB_CRUSR_NAME = dacBPSN.Get員工姓名(mainRec.DB_CRUSR);
|
|
mainRec.DB_TRUSR_NAME = dacBPSN.Get員工姓名(mainRec.DB_TRUSR);
|
|
|
|
var existingLabor = dacLabor.SelectOne(no).FirstOrDefault();
|
|
if (existingLabor != null)
|
|
{
|
|
mainRec.勞務費_編號 = existingLabor.編號;
|
|
mainRec.勞務費_費用別 = existingLabor.費用別;
|
|
mainRec.勞務費_單價 = existingLabor.單價;
|
|
mainRec.勞務費_數量 = existingLabor.數量;
|
|
mainRec.勞務費_單位 = existingLabor.單位;
|
|
mainRec.勞務費_扣繳類別 = existingLabor.扣繳類別;
|
|
mainRec.勞務費_合計金額 = existingLabor.合計金額;
|
|
mainRec.勞務費_應扣繳稅額 = existingLabor.應扣繳稅額;
|
|
mainRec.勞務費_服務費 = existingLabor.服務費;
|
|
mainRec.勞務費_作廢 = existingLabor.作廢;
|
|
}
|
|
|
|
var existingTravel = dacTravel.SelectOne(no).FirstOrDefault();
|
|
if (existingTravel != null)
|
|
{
|
|
mainRec.差旅費_編號 = existingTravel.編號;
|
|
mainRec.差旅費_票價資訊 = existingTravel.票價資訊;
|
|
mainRec.差旅費_費用別 = existingTravel.費用別;
|
|
mainRec.差旅費_起點 = existingTravel.起點;
|
|
mainRec.差旅費_訖點 = existingTravel.訖點;
|
|
mainRec.差旅費_捷運公車 = existingTravel.捷運公車;
|
|
mainRec.差旅費_火車 = existingTravel.火車;
|
|
mainRec.差旅費_計程車 = existingTravel.計程車;
|
|
mainRec.差旅費_高鐵飛機 = existingTravel.高鐵飛機;
|
|
mainRec.差旅費_自行開車 = existingTravel.自行開車;
|
|
mainRec.差旅費_過路費停車費 = existingTravel.過路費停車費;
|
|
mainRec.差旅費_住宿費 = existingTravel.住宿費;
|
|
mainRec.差旅費_合計 = existingTravel.合計;
|
|
mainRec.差旅費_作廢 = existingTravel.作廢;
|
|
}
|
|
return ServiceResponse.CreateSuccess("OK", data: mainRec);
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"取得資料失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse Save(bool isNew, 領據Item mainItem, 勞務費Item laborItem, 差旅費Item travelItem)
|
|
{
|
|
try
|
|
{
|
|
using (var ts = DAC.NewTransactionScope())
|
|
{
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
DAC_領據 dacMain = new DAC_領據(conn);
|
|
DAC_勞務費 dacLabor = new DAC_勞務費(conn);
|
|
DAC_差旅費 dacTravel = new DAC_差旅費(conn);
|
|
|
|
// 後端驗證:勞務費有金額但費用別或單位未填
|
|
if (laborItem != null && !dacLabor.IsEmpty(laborItem))
|
|
{
|
|
if (string.IsNullOrEmpty(laborItem.費用別))
|
|
return ServiceResponse.CreateError("勞務費已輸入金額,請選擇費用別");
|
|
if (string.IsNullOrEmpty(laborItem.單位))
|
|
return ServiceResponse.CreateError("勞務費已輸入金額,請選擇單位");
|
|
}
|
|
|
|
if (isNew)
|
|
{
|
|
mainItem = dacMain.InsertOne(mainItem);
|
|
|
|
if (laborItem != null && !dacLabor.IsEmpty(laborItem))
|
|
{
|
|
laborItem.領據編號 = mainItem.編號;
|
|
dacLabor.InsertOne(laborItem);
|
|
}
|
|
|
|
if (travelItem != null && !dacTravel.IsEmpty(travelItem))
|
|
{
|
|
travelItem.領據編號 = mainItem.編號;
|
|
dacTravel.InsertOne(travelItem);
|
|
}
|
|
ts.Complete();
|
|
|
|
return ServiceResponse.CreateSuccess("新增成功", mainItem);
|
|
}
|
|
else
|
|
{
|
|
dacMain.UpdateOne(mainItem);
|
|
|
|
if (laborItem != null && laborItem.領據編號 > 0)
|
|
{
|
|
var existingLabor = dacLabor.SelectOne(mainItem.編號);
|
|
if (existingLabor.Count > 0)
|
|
{
|
|
laborItem.DB_APPNO = existingLabor.FirstOrDefault().DB_APPNO;
|
|
dacLabor.UpdateOne(laborItem);
|
|
}
|
|
else if (!dacLabor.IsEmpty(laborItem))
|
|
{
|
|
dacLabor.InsertOne(laborItem);
|
|
}
|
|
}
|
|
|
|
if (travelItem != null && travelItem.領據編號 > 0)
|
|
{
|
|
var existingTravel = dacTravel.SelectOne(mainItem.編號);
|
|
if (existingTravel.Count > 0)
|
|
{
|
|
travelItem.DB_APPNO = existingTravel.FirstOrDefault().DB_APPNO;
|
|
dacTravel.UpdateOne(travelItem);
|
|
}
|
|
else if (!dacTravel.IsEmpty(travelItem))
|
|
{
|
|
dacTravel.InsertOne(travelItem);
|
|
}
|
|
}
|
|
ts.Complete();
|
|
|
|
return ServiceResponse.CreateSuccess("修改成功");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"儲存失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse Delete(int no, int dbAppNo)
|
|
{
|
|
try
|
|
{
|
|
using (var ts = DAC.NewTransactionScope())
|
|
{
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
DAC_領據 dacMain = new DAC_領據(conn);
|
|
DAC_勞務費 dacLabor = new DAC_勞務費(conn);
|
|
DAC_差旅費 dacTravel = new DAC_差旅費(conn);
|
|
|
|
var existingLabor = dacLabor.SelectOne(no);
|
|
if (existingLabor.Count > 0)
|
|
{
|
|
dacLabor.DeleteOne(no, existingLabor[0].DB_APPNO);
|
|
}
|
|
|
|
var existingTravel = dacTravel.SelectOne(no);
|
|
if (existingTravel.Count > 0)
|
|
{
|
|
dacTravel.DeleteOne(no, existingTravel[0].DB_APPNO);
|
|
}
|
|
|
|
dacMain.DeleteOne(no, dbAppNo);
|
|
ts.Complete();
|
|
|
|
return ServiceResponse.CreateSuccess("刪除成功");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"刪除失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse Void(int no)
|
|
{
|
|
try
|
|
{
|
|
using (var conn = DAC.NewConnection()) {
|
|
|
|
DAC_領據 dacMain = new DAC_領據(conn);
|
|
DAC_勞務費 dacLabor = new DAC_勞務費(conn);
|
|
DAC_差旅費 dacTravel = new DAC_差旅費(conn);
|
|
DAC_組織人員 dacOrgnization = new DAC_組織人員(conn);
|
|
|
|
var mainItem = dacMain.SelectOne(no).FirstOrDefault();
|
|
if (mainItem == null)
|
|
{
|
|
return ServiceResponse.CreateError("找不到指定的領據");
|
|
}
|
|
|
|
mainItem.作廢 = (mainItem.作廢 == 1) ? 0 : 1;
|
|
|
|
// 取消作廢只有總管理處財務部可以執行
|
|
if (mainItem.作廢 == 0 && !dacOrgnization.Is人員屬於組織(PublicVariable.財務部ID, CurrentUserId))
|
|
{
|
|
return ServiceResponse.CreateError("財務部人員才可以取消作廢");
|
|
}
|
|
|
|
var laborItem = dacLabor.SelectOne(no).FirstOrDefault();
|
|
var travelItem = dacTravel.SelectOne(no).FirstOrDefault();
|
|
|
|
dacMain.UpdateOne(mainItem);
|
|
|
|
if (laborItem != null)
|
|
{
|
|
laborItem.作廢 = mainItem.作廢;
|
|
dacLabor.UpdateOne(laborItem);
|
|
}
|
|
if (travelItem != null)
|
|
{
|
|
travelItem.作廢 = mainItem.作廢;
|
|
dacTravel.UpdateOne(travelItem);
|
|
}
|
|
|
|
string action = mainItem.作廢 == 1 ? "作廢" : "取消作廢";
|
|
return ServiceResponse.CreateSuccess($"{action}成功");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"作廢操作失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse VoidLaborFee(int receiptNo)
|
|
{
|
|
try
|
|
{
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
DAC_勞務費 dacLabor = new DAC_勞務費(conn);
|
|
DAC_組織人員 dacOrgnization = new DAC_組織人員(conn);
|
|
var item = dacLabor.SelectOne(receiptNo).FirstOrDefault();
|
|
if (item == null)
|
|
{
|
|
return ServiceResponse.CreateError("找不到指定的勞務費資料");
|
|
}
|
|
|
|
item.作廢 = (item.作廢 == 1) ? 0 : 1;
|
|
|
|
// 取消作廢只有總管理處財務部可以執行
|
|
if (item.作廢 == 0 && !dacOrgnization.Is人員屬於組織(PublicVariable.財務部ID, CurrentUserId))
|
|
{
|
|
return ServiceResponse.CreateError("財務部人員才可以取消作廢");
|
|
}
|
|
|
|
dacLabor.UpdateOne(item);
|
|
|
|
string action = item.作廢 == 1 ? "作廢" : "取消作廢";
|
|
return ServiceResponse.CreateSuccess($"勞務費{action}成功");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"勞務費作廢操作失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse VoidTravelFee(int receiptNo)
|
|
{
|
|
try
|
|
{
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
DAC_差旅費 dacTravel = new DAC_差旅費(conn);
|
|
DAC_組織人員 dacOrgnization = new DAC_組織人員(conn);
|
|
var item = dacTravel.SelectOne(receiptNo).FirstOrDefault();
|
|
|
|
if (item == null)
|
|
{
|
|
return ServiceResponse.CreateError("找不到指定的差旅費資料");
|
|
}
|
|
|
|
item.作廢 = (item.作廢 == 1) ? 0 : 1;
|
|
|
|
// 取消作廢只有總管理處財務部可以執行
|
|
if (item.作廢 == 0 && !dacOrgnization.Is人員屬於組織(PublicVariable.財務部ID, CurrentUserId))
|
|
{
|
|
return ServiceResponse.CreateError("財務部人員才可以取消作廢");
|
|
}
|
|
|
|
dacTravel.UpdateOne(item);
|
|
|
|
string action = item.作廢 == 1 ? "作廢" : "取消作廢";
|
|
return ServiceResponse.CreateSuccess($"差旅費{action}成功");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"差旅費作廢操作失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse CalcTax(int laborFee, string category)
|
|
{
|
|
try
|
|
{
|
|
int tax = 0;
|
|
|
|
if (category != null)
|
|
{
|
|
if ((category.StartsWith("9A") || category.StartsWith("9B")) && laborFee > PublicVariable.領據執行業務所得課稅門檻)
|
|
{
|
|
tax = (int)Math.Round(laborFee * PublicVariable.領據執行業務所得稅率, MidpointRounding.AwayFromZero);
|
|
}
|
|
else if (category.StartsWith("50") && laborFee >= PublicVariable.領據薪資課稅門檻)
|
|
{
|
|
tax = (int)Math.Round(laborFee * PublicVariable.領據薪資稅率, MidpointRounding.AwayFromZero);
|
|
}
|
|
}
|
|
|
|
return ServiceResponse.CreateSuccess("計算成功", tax);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"計算稅額失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse SearchRecipient(string key, string identity, DateTime? activationDate)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(key))
|
|
{
|
|
return ServiceResponse.CreateSuccess("查詢成功", new List<dynamic>());
|
|
}
|
|
|
|
var result = new List<dynamic>();
|
|
|
|
using (var conn = DAC.NewConnection()) {
|
|
if (identity == "講師")
|
|
{
|
|
DAC_講師 dacInstructor = new DAC_講師(conn);
|
|
DAC_付款設定 dacPaymentSetting = new DAC_付款設定(conn);
|
|
var instructors = dacInstructor.SelectByKeyword(key);
|
|
|
|
foreach (var item in instructors)
|
|
{
|
|
var paymentSetting = dacPaymentSetting.SelectRecentlyActivated(item.付款設定講師編號, activationDate);
|
|
result.Add(new
|
|
{
|
|
Name = item.姓名,
|
|
IdNumber = item.身份證字號,
|
|
Value = item.編號.ToString(),
|
|
VoucherType = paymentSetting?.憑證類別,
|
|
ConductType = paymentSetting?.扣繳類別,
|
|
});
|
|
}
|
|
}
|
|
else if (identity == "非講師")
|
|
{
|
|
DAC_非講師 dacNonInstructor = new DAC_非講師(conn);
|
|
DAC_付款設定 dacPaymentSetting = new DAC_付款設定(conn);
|
|
var nonInstructors = dacNonInstructor.SelectByKeyword(key);
|
|
|
|
foreach (var item in nonInstructors)
|
|
{
|
|
var paymentSetting = dacPaymentSetting.SelectRecentlyActivated(item.編號, activationDate);
|
|
result.Add(new
|
|
{
|
|
Name = item.姓名,
|
|
IdNumber = item.身分證字號,
|
|
Value = item.編號,
|
|
VoucherType = paymentSetting?.憑證類別,
|
|
ConductType = paymentSetting?.扣繳類別,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (result.Count > 0)
|
|
return ServiceResponse.CreateSuccess("查詢成功", result);
|
|
return ServiceResponse.CreateError($"無符合資料");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"搜尋失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse SearchPlan(string key, int year = 0)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(key))
|
|
{
|
|
return ServiceResponse.CreateSuccess("查詢成功", new List<dynamic>());
|
|
}
|
|
|
|
key = key.ToUpper();
|
|
|
|
var result = new List<dynamic>();
|
|
DAC_BPAA dac = new DAC_BPAA();
|
|
DataTable dtPlans, dtPlansAdditional = null;
|
|
if (year > 0)
|
|
{
|
|
dtPlans = dac.GetBpaaWithTYPlusNone(year);
|
|
if (year == 115)
|
|
{
|
|
dtPlansAdditional = dac.GetBpaaWithTYPlusNone(114);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dtPlans = dac.GetBpaaWithTYPlusNone();
|
|
}
|
|
|
|
if (dtPlans != null && dtPlans.Rows.Count > 0)
|
|
{
|
|
if (dtPlansAdditional != null)
|
|
{
|
|
foreach (DataRow row in dtPlansAdditional.Select("BPPYN = '114AG114003'"))
|
|
{
|
|
dtPlans.ImportRow(row);
|
|
}
|
|
}
|
|
|
|
foreach (DataRow row in dtPlans.Rows)
|
|
{
|
|
string planCode = row["BPPYN"].ToString();
|
|
string planName = row["BPPYM"].ToString();
|
|
|
|
if (planCode.Contains(key) || planName.Contains(key))
|
|
{
|
|
result.Add(new
|
|
{
|
|
Name = planName,
|
|
Code = planCode,
|
|
Value = planCode
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (result.Count > 0)
|
|
return ServiceResponse.CreateSuccess("查詢成功", result);
|
|
return ServiceResponse.CreateError($"無符合資料");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"搜尋計畫失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse GetDropdownLists(string key)
|
|
{
|
|
try
|
|
{
|
|
NameValueList result = null;
|
|
|
|
switch (key)
|
|
{
|
|
case "身分別":
|
|
result = 身分別.InputSelectList; break;
|
|
case "憑證類別":
|
|
result = 憑證類別.InputSelectList; break;
|
|
case "付款方式":
|
|
result = 付款方式.InputSelectList; break;
|
|
case "扣繳類別":
|
|
result = 扣繳類別.InputSelectList; break;
|
|
case "勞務費_費用別":
|
|
result = 勞務費_費用別.InputSelectList; break;
|
|
case "差旅費_費用別":
|
|
result = 差旅費_費用別.InputSelectList; break;
|
|
case "單位別":
|
|
result = 單位別.InputSelectList; break;
|
|
}
|
|
if (result != null)
|
|
return ServiceResponse.CreateSuccess("取得下拉選單資料成功", result);
|
|
return ServiceResponse.CreateError($"取得下拉選單資料失敗:找不到對應的下拉選單");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"取得下拉選單資料失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse GetSearchDropdownLists(string key)
|
|
{
|
|
try
|
|
{
|
|
NameValueList result = null;
|
|
|
|
switch (key)
|
|
{
|
|
case "身分別":
|
|
result = 身分別.SearchSelectList; break;
|
|
case "憑證類別":
|
|
result = 憑證類別.SearchSelectList; break;
|
|
case "付款方式":
|
|
result = 付款方式.SearchSelectList; break;
|
|
case "扣繳類別":
|
|
result = 扣繳類別.SearchSelectList; break;
|
|
case "勞務費_費用別":
|
|
result = 勞務費_費用別.SearchSelectList; break;
|
|
case "差旅費_費用別":
|
|
result = 差旅費_費用別.SearchSelectList; break;
|
|
case "單位別":
|
|
result = 單位別.SearchSelectList; break;
|
|
}
|
|
if (result != null)
|
|
return ServiceResponse.CreateSuccess("取得下拉選單資料成功", result);
|
|
return ServiceResponse.CreateError($"取得下拉選單資料失敗:找不到對應的下拉選單");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"取得查詢下拉選單資料失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse GetPhraseLists()
|
|
{
|
|
try
|
|
{
|
|
using (var conn = DAC.NewConnection()) {
|
|
var daoPhrase = new DAC_片語(conn);
|
|
var result = new
|
|
{
|
|
activityLocation = daoPhrase.SelectBy適用欄位("活動地點").Select(p => p.片語內容).ToList(),
|
|
activityCategory = daoPhrase.SelectBy適用欄位("活動類別").Select(p => p.片語內容).ToList(),
|
|
ticketPrice = daoPhrase.SelectBy適用欄位("票價資訊").Select(p => p.片語內容).ToList()
|
|
};
|
|
return ServiceResponse.CreateSuccess("取得片語清單成功", result);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"取得片語清單失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse GetClosingMonth()
|
|
{
|
|
try
|
|
{
|
|
// 返回預設值,實際實作應該從 BWEX 表查詢
|
|
// BSNUM = '領據關帳年月', BSITM = ' 1', BSNAM = 關帳年月 (YYYY-MM 格式)
|
|
var result = new
|
|
{
|
|
currentClosingMonth = new DAC_BWEX().ReadSetting("領據關帳年月", 1)
|
|
};
|
|
return ServiceResponse.CreateSuccess("取得關帳年月成功", result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"取得關帳年月失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse UpdateClosingMonth(string closingMonth)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(closingMonth))
|
|
{
|
|
return ServiceResponse.CreateError("關帳年月不能為空");
|
|
}
|
|
|
|
// 驗證格式 YYYY-MM
|
|
if (!System.Text.RegularExpressions.Regex.IsMatch(closingMonth, @"^\d{4}-\d{2}$"))
|
|
{
|
|
return ServiceResponse.CreateError("關帳年月格式不正確,請使用 YYYY-MM 格式");
|
|
}
|
|
|
|
// 實作應該在此處更新 BWEX 表
|
|
PublicVariable.領據關帳年月 = closingMonth;
|
|
|
|
return ServiceResponse.CreateSuccess("關帳年月已成功更新");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"更新關帳年月失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse Print(List<int> idList)
|
|
{
|
|
try
|
|
{
|
|
if (idList == null || idList.Count == 0)
|
|
{
|
|
return ServiceResponse.CreateError("未指定要列印的領據");
|
|
}
|
|
|
|
try
|
|
{
|
|
using (var ts = DAC.NewTransactionScope())
|
|
{
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
DAC_領據 dacMain = new DAC_領據(conn);
|
|
DAC_勞務費 dacLabor = new DAC_勞務費(conn);
|
|
DAC_差旅費 dacTravel = new DAC_差旅費(conn);
|
|
DAC_講師 dac講師 = new DAC_講師(conn);
|
|
DAC_非講師 dac非講師 = new DAC_非講師(conn);
|
|
|
|
// 收集所有要列印的領據資料
|
|
List<PrintData> printDataList = new List<PrintData>();
|
|
|
|
// 無資料清單
|
|
List<string> noDataList = new List<string>();
|
|
|
|
foreach (var id in idList)
|
|
{
|
|
var mainRec = dacMain.SelectOne(id).FirstOrDefault();
|
|
if (mainRec == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (mainRec.作廢 != 0)
|
|
{
|
|
noDataList.Add(mainRec.表單編號);
|
|
continue;
|
|
}
|
|
|
|
// 取得講師非講師資料
|
|
講師 講師 = null;
|
|
非講師Item 非講師 = null;
|
|
if (mainRec.身分別 == "講師")
|
|
{
|
|
講師 = dac講師.SelectOne(DAC.GetInt32(mainRec.講師_非講師編號)).FirstOrDefault();
|
|
}
|
|
else
|
|
{
|
|
非講師 = dac非講師.SelectOne(mainRec.講師_非講師編號).FirstOrDefault();
|
|
}
|
|
|
|
// 取得勞務費資料
|
|
var laborItem = dacLabor.SelectOne(id).Where(p => p.作廢 != 1).FirstOrDefault();
|
|
if (laborItem != null)
|
|
{
|
|
// 若勞務費編號為空,需要給勞務費自動編號
|
|
if (string.IsNullOrEmpty(laborItem.編號) && !laborItem.IsEmpty)
|
|
{
|
|
laborItem.編號 = dacLabor.Next單號(mainRec.活動日期, "勞務費", "編號", "'T'CCCMM<9999>", "");
|
|
dacLabor.UpdateOne(laborItem);
|
|
}
|
|
}
|
|
|
|
// 取得差旅費資料
|
|
var travelItem = dacTravel.SelectOne(id).Where(p => p.作廢 != 1).FirstOrDefault();
|
|
if (travelItem != null && travelItem.合計.HasValue && travelItem.合計 > 0)
|
|
{
|
|
// 若差旅費編號為空,需要給差旅費自動編號
|
|
if (string.IsNullOrEmpty(travelItem.編號) && !travelItem.IsEmpty)
|
|
{
|
|
travelItem.編號 = dacTravel.Next單號(mainRec.活動日期, "差旅費", "編號", "'E'CCCMM<9999>", "");
|
|
dacTravel.UpdateOne(travelItem);
|
|
}
|
|
}
|
|
|
|
if (laborItem != null && !laborItem.IsEmpty || travelItem != null && !travelItem.IsEmpty)
|
|
{
|
|
if (mainRec.憑證類別 == 憑證類別.憑證類別_領據)
|
|
{
|
|
mainRec.列印次數 = mainRec.列印次數.HasValue ? mainRec.列印次數.Value + 1 : 1;
|
|
dacMain.UpdateOne(mainRec);
|
|
|
|
printDataList.Add(new PrintData
|
|
{
|
|
Main = mainRec,
|
|
Labor = laborItem,
|
|
Travel = travelItem,
|
|
講師 = 講師,
|
|
非講師 = 非講師
|
|
});
|
|
}
|
|
else
|
|
{
|
|
noDataList.Add($"{mainRec.表單編號} 憑證類別不是領據");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
noDataList.Add($"{mainRec.表單編號} 無資料或已作廢");
|
|
}
|
|
}
|
|
|
|
// 更新單據欄位
|
|
ts.Complete();
|
|
|
|
if (printDataList.Count == 0)
|
|
{
|
|
return ServiceResponse.CreateSuccess($"{string.Join("、", noDataList.ToArray())}");
|
|
}
|
|
|
|
// 生成 Excel 檔案
|
|
Report.領據列印 report = new Report.領據列印();
|
|
System.IO.MemoryStream ms = report.DoReport(printDataList);
|
|
|
|
// 轉換為 Base64 編碼
|
|
string excelBase64 = Convert.ToBase64String(ms.ToArray());
|
|
|
|
// 生成檔案名稱
|
|
string fileName = string.Format("領據{0}_{1:yyyyMMddHHmmss}.xlsx"
|
|
, (printDataList.Count > 0 ? string.Format("_{0}_{1}", printDataList[0].Main.領款人姓名, printDataList[0].Main.表單編號) : String.Empty)
|
|
, PublicVariable.TaiwanNow);
|
|
|
|
return ServiceResponse.CreateSuccess("列印成功", new
|
|
{
|
|
fileName = fileName,
|
|
excelData = excelBase64,
|
|
count = printDataList.Count
|
|
});
|
|
}
|
|
}
|
|
}
|
|
catch (Exception innerEx)
|
|
{
|
|
return ServiceResponse.CreateError(string.Format("列印處理失敗:{0}", innerEx.Message));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError(string.Format("列印失敗:{0}", ex.Message));
|
|
}
|
|
}
|
|
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse Export(
|
|
DateTime? 活動日期_1 = null,
|
|
DateTime? 活動日期_2 = null,
|
|
string 身分別 = null,
|
|
string 講師_非講師編號 = null,
|
|
string 憑證類別 = null,
|
|
string 計畫代號 = null,
|
|
string 計畫名稱 = null,
|
|
string 活動類別 = null,
|
|
string 付款方式 = null,
|
|
string 領款人姓名 = null,
|
|
string orderBy = "")
|
|
{
|
|
try
|
|
{
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
DAC_領據 dacMain = new DAC_領據(conn);
|
|
|
|
var data = dacMain.SelectPageWithRelations(
|
|
noInputReturnAll: true,
|
|
startRowIndex: 0,
|
|
maximumRows: Int32.MaxValue,
|
|
活動日期_1: 活動日期_1,
|
|
活動日期_2: 活動日期_2,
|
|
身分別: 身分別,
|
|
講師_非講師編號: 講師_非講師編號,
|
|
憑證類別: 憑證類別,
|
|
計畫代號: 計畫代號,
|
|
計畫名稱: 計畫名稱,
|
|
活動類別: 活動類別,
|
|
付款方式: 付款方式,
|
|
orderBy: orderBy
|
|
);
|
|
|
|
// 生成 Excel 檔案
|
|
Report.領據匯出 report = new Report.領據匯出();
|
|
report.data = data;
|
|
System.IO.MemoryStream ms = report.DoReport();
|
|
|
|
// 轉換為 Base64 編碼
|
|
string excelBase64 = Convert.ToBase64String(ms.ToArray());
|
|
|
|
// 生成檔案名稱
|
|
string fileName = string.Format("領據匯出_{0:yyyyMMdd_HHmmss}.xlsx", PublicVariable.TaiwanNow);
|
|
|
|
return ServiceResponse.CreateSuccess("匯出成功", new
|
|
{
|
|
fileName = fileName,
|
|
excelData = excelBase64
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError(string.Format("匯出失敗:{0}", ex.Message));
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse GetVariables()
|
|
{
|
|
return ServiceResponse.CreateSuccess("OK", data: new {
|
|
領據執行業務所得課稅門檻 = PublicVariable.領據執行業務所得課稅門檻,
|
|
領據薪資課稅門檻 = PublicVariable.領據薪資課稅門檻,
|
|
領據基本工資 = PublicVariable.領據基本工資,
|
|
領據執行業務所得稅率 = PublicVariable.領據執行業務所得稅率,
|
|
領據薪資稅率 = PublicVariable.領據薪資稅率
|
|
});
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse SearchSummaryTable(
|
|
string 起日,
|
|
string 迄日,
|
|
string 身分別,
|
|
string 付款方式,
|
|
string 輸出方式)
|
|
{
|
|
try
|
|
{
|
|
// 解析日期參數
|
|
DateTime? startDate = null;
|
|
DateTime? endDate = null;
|
|
|
|
if (!string.IsNullOrEmpty(起日))
|
|
{
|
|
if (DateTime.TryParse(起日, out var parsedStartDate))
|
|
{
|
|
startDate = parsedStartDate;
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(迄日))
|
|
{
|
|
if (DateTime.TryParse(迄日, out var parsedEndDate))
|
|
{
|
|
endDate = parsedEndDate;
|
|
}
|
|
}
|
|
|
|
// 驗證輸出方式
|
|
if (string.IsNullOrEmpty(輸出方式) || (輸出方式 != "DATA" && 輸出方式 != "EXPORT"))
|
|
{
|
|
return ServiceResponse.CreateError("輸出方式無效");
|
|
}
|
|
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
var dao領據 = new DAC_領據(conn);
|
|
var summaryData = dao領據.SelectSummary(true, 0, int.MaxValue, startDate, endDate, 身分別, 付款方式);
|
|
|
|
if (輸出方式 == "DATA")
|
|
{
|
|
return ServiceResponse.CreateSuccess("查詢成功", summaryData);
|
|
}
|
|
else
|
|
{
|
|
var report = new 講師個人費用彙整表();
|
|
report.起日 = startDate;
|
|
report.迄日 = endDate;
|
|
report.身分別 = 身分別;
|
|
report.付款方式 = 付款方式;
|
|
report.data = summaryData;
|
|
var ms = report.DoReport();
|
|
|
|
// 轉換為 Base64 編碼
|
|
string excelBase64 = Convert.ToBase64String(ms.ToArray());
|
|
|
|
var excelResult = new
|
|
{
|
|
excelData = excelBase64,
|
|
fileName = $"講師個人費用彙整表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
|
};
|
|
|
|
return ServiceResponse.CreateSuccess("匯出成功", excelResult);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"查詢失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse SearchDetailTable(
|
|
string 起日,
|
|
string 迄日,
|
|
string 身分別,
|
|
string 憑證類別,
|
|
string 輸出方式)
|
|
{
|
|
try
|
|
{
|
|
// 解析日期參數
|
|
DateTime? startDate = null;
|
|
DateTime? endDate = null;
|
|
|
|
if (!string.IsNullOrEmpty(起日))
|
|
{
|
|
if (DateTime.TryParse(起日, out var parsedStartDate))
|
|
{
|
|
startDate = parsedStartDate;
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(迄日))
|
|
{
|
|
if (DateTime.TryParse(迄日, out var parsedEndDate))
|
|
{
|
|
endDate = parsedEndDate;
|
|
}
|
|
}
|
|
|
|
// 驗證輸出方式
|
|
if (string.IsNullOrEmpty(輸出方式) || (輸出方式 != "DATA" && 輸出方式 != "EXPORT_SUMMARY" && 輸出方式 != "EXPORT_DETAIL"))
|
|
{
|
|
return ServiceResponse.CreateError("輸出方式無效");
|
|
}
|
|
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
var dao領據 = new DAC_領據(conn);
|
|
|
|
if (輸出方式 == "EXPORT_SUMMARY")
|
|
{
|
|
var detailData = dao領據.SelectDetail(true, 0, int.MaxValue, startDate, endDate, 身分別, 憑證類別);
|
|
var report = new 扣繳彙整表();
|
|
report.起日 = startDate;
|
|
report.迄日 = endDate;
|
|
report.身分別 = 身分別;
|
|
report.憑證類別 = 憑證類別;
|
|
report.data = detailData;
|
|
var ms = report.DoReport();
|
|
|
|
// 轉換為 Base64 編碼
|
|
string excelBase64 = Convert.ToBase64String(ms.ToArray());
|
|
|
|
var excelResult = new
|
|
{
|
|
excelData = excelBase64,
|
|
fileName = $"扣繳彙整表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
|
};
|
|
|
|
return ServiceResponse.CreateSuccess("匯出成功", excelResult);
|
|
}
|
|
else if (輸出方式 == "EXPORT_DETAIL")
|
|
{
|
|
var detailData = dao領據.SelectDetail(true, 0, int.MaxValue, startDate, endDate, 身分別, 憑證類別);
|
|
var reportData = new List<扣繳明細Item>();
|
|
foreach (var d in detailData)
|
|
{
|
|
reportData.AddRange(d.明細);
|
|
}
|
|
var report = new 扣繳明細表();
|
|
report.起日 = startDate;
|
|
report.迄日 = endDate;
|
|
report.身分別 = 身分別;
|
|
report.憑證類別 = 憑證類別;
|
|
report.data = reportData;
|
|
var ms = report.DoReport();
|
|
|
|
// 轉換為 Base64 編碼
|
|
string excelBase64 = Convert.ToBase64String(ms.ToArray());
|
|
|
|
var excelResult = new
|
|
{
|
|
excelData = excelBase64,
|
|
fileName = $"扣繳明細表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
|
};
|
|
|
|
return ServiceResponse.CreateSuccess("匯出成功", excelResult);
|
|
}
|
|
else
|
|
{
|
|
var detailData = dao領據.SelectDetail(true, 0, int.MaxValue, startDate, endDate, 身分別, 憑證類別);
|
|
return ServiceResponse.CreateSuccess("查詢成功", detailData);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"查詢失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse SendEmail(
|
|
string 起日,
|
|
string 迄日,
|
|
string 身分別,
|
|
string 憑證類別,
|
|
string 輸出方式,
|
|
List<string> 講師非講師編號,
|
|
string 寄件人郵箱,
|
|
string 郵件主旨,
|
|
string 郵件內文)
|
|
{
|
|
try
|
|
{
|
|
// 解析日期參數
|
|
DateTime? startDate = null;
|
|
DateTime? endDate = null;
|
|
|
|
if (!string.IsNullOrEmpty(起日))
|
|
{
|
|
if (DateTime.TryParse(起日, out var parsedStartDate))
|
|
{
|
|
startDate = parsedStartDate;
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(迄日))
|
|
{
|
|
if (DateTime.TryParse(迄日, out var parsedEndDate))
|
|
{
|
|
endDate = parsedEndDate;
|
|
}
|
|
}
|
|
|
|
// 驗證輸出方式
|
|
if (string.IsNullOrEmpty(輸出方式) || (輸出方式 != "PREVIEW" && 輸出方式 != "SENDMAIL"))
|
|
{
|
|
return ServiceResponse.CreateError("輸出方式無效");
|
|
}
|
|
|
|
// 驗證輸入參數
|
|
if (講師非講師編號 == null || 講師非講師編號.Count == 0)
|
|
{
|
|
return ServiceResponse.CreateError("請選擇至少一個收件者");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(寄件人郵箱))
|
|
{
|
|
return ServiceResponse.CreateError("請輸入寄件人郵箱");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(郵件主旨))
|
|
{
|
|
return ServiceResponse.CreateError("請輸入郵件主旨");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(郵件內文))
|
|
{
|
|
return ServiceResponse.CreateError("請輸入郵件內文");
|
|
}
|
|
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
var dao領據 = new DAC_領據(conn);
|
|
var detailData = dao領據.SelectDetail(true, 0, int.MaxValue, startDate, endDate, 身分別, 憑證類別);
|
|
var previewData = new List<扣繳匯總郵件Item>();
|
|
foreach (var d in detailData)
|
|
{
|
|
if (講師非講師編號.FirstOrDefault(x => x == d.講師_非講師編號) == null)
|
|
continue;
|
|
|
|
var p = new 扣繳匯總郵件Item();
|
|
p.收件人姓名 = d.領款人姓名;
|
|
p.收件人郵箱 = d.電子郵件;
|
|
p.主旨 = 郵件主旨;
|
|
p.內文 = 郵件內文;
|
|
p.明細 = d.明細;
|
|
p.講師勞務費合計 = p.明細.Sum(x => x.講師勞務費);
|
|
p.應扣繳稅額合計 = p.明細.Sum(x => x.應扣繳稅額);
|
|
p.服務費合計 = p.明細.Sum(x => x.服務費);
|
|
previewData.Add(p);
|
|
}
|
|
|
|
if (輸出方式 == "PREVIEW")
|
|
{
|
|
return ServiceResponse.CreateSuccess("預覽成功", previewData);
|
|
}
|
|
else
|
|
{
|
|
var 發送郵件 = new 發送郵件();
|
|
發送郵件.Context = this.Context;
|
|
var successCount = 0;
|
|
var failCount = 0;
|
|
var failMessages = new List<string>();
|
|
foreach (var d in previewData)
|
|
{
|
|
var sendResult = 發送郵件.發送扣繳明細表郵件(寄件人郵箱, startDate, endDate, d, out string message);
|
|
if (!sendResult)
|
|
{
|
|
failCount++;
|
|
failMessages.Add(message);
|
|
}
|
|
else
|
|
{
|
|
successCount++;
|
|
}
|
|
}
|
|
if (failCount == 0)
|
|
return ServiceResponse.CreateSuccess($"郵件已成功發送給 {successCount} 位收件者");
|
|
else
|
|
return ServiceResponse.CreateSuccess($"郵件已成功發送給 {successCount} 位收件者,但有 {failCount} 封發送失敗");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"處理失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse ValidateImportFile(string filePath)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
|
|
{
|
|
return ServiceResponse.CreateError("檔案不存在");
|
|
}
|
|
|
|
// 驗證副檔名
|
|
string extension = System.IO.Path.GetExtension(filePath).ToLower();
|
|
if (extension != ".xls" && extension != ".xlsx")
|
|
{
|
|
return ServiceResponse.CreateError("只允許上傳 .xls 或 .xlsx 檔案");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 驗證欄位格式
|
|
var importer = new 領據匯入();
|
|
List<string> errors = importer.Validate(filePath, typeof(領據匯入Item), out int rowCount);
|
|
|
|
if (errors.Count > 0)
|
|
{
|
|
// 清除臨時檔案
|
|
if (System.IO.File.Exists(filePath))
|
|
System.IO.File.Delete(filePath);
|
|
|
|
return ServiceResponse.CreateSuccess("檔案驗證失敗", new
|
|
{
|
|
Success = false,
|
|
Errors = errors,
|
|
RowCount = 0
|
|
});
|
|
}
|
|
|
|
// 驗證欄位內容
|
|
List<string> contentErrors = importer.ValidateContent(filePath);
|
|
|
|
if (contentErrors.Count > 0)
|
|
{
|
|
// 清除臨時檔案
|
|
if (System.IO.File.Exists(filePath))
|
|
System.IO.File.Delete(filePath);
|
|
|
|
return ServiceResponse.CreateSuccess("檔案驗證失敗", new
|
|
{
|
|
Success = false,
|
|
Errors = contentErrors,
|
|
RowCount = 0
|
|
});
|
|
}
|
|
|
|
// 驗證重複資料
|
|
List<string> duplicateErrors;
|
|
List<string> duplicateWarnings;
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
importer.ValidateDuplicates(filePath, conn, out duplicateErrors, out duplicateWarnings);
|
|
}
|
|
|
|
if (duplicateErrors.Count > 0)
|
|
{
|
|
// 與資料庫重複超過 5 筆,不允許匯入
|
|
if (System.IO.File.Exists(filePath))
|
|
System.IO.File.Delete(filePath);
|
|
|
|
return ServiceResponse.CreateSuccess("檔案驗證失敗", new
|
|
{
|
|
Success = false,
|
|
Errors = duplicateErrors,
|
|
RowCount = 0
|
|
});
|
|
}
|
|
|
|
// 儲存檔案路徑到 Session,以便匯入時使用
|
|
HttpContext.Current.Session["ImportFilePath"] = filePath;
|
|
|
|
return ServiceResponse.CreateSuccess("驗證成功", new
|
|
{
|
|
Success = true,
|
|
Errors = new List<string>(),
|
|
Warnings = duplicateWarnings,
|
|
RowCount = rowCount
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// 清除臨時檔案
|
|
if (System.IO.File.Exists(filePath))
|
|
System.IO.File.Delete(filePath);
|
|
|
|
return ServiceResponse.CreateError($"驗證過程中發生錯誤:{ex.Message}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"驗證失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse ImportReceiptData()
|
|
{
|
|
try
|
|
{
|
|
// 從 Session 中取得檔案路徑
|
|
string filePath = HttpContext.Current?.Session?["ImportFilePath"]?.ToString();
|
|
|
|
if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
|
|
{
|
|
return ServiceResponse.CreateError("檔案不存在或已過期,請重新上傳");
|
|
}
|
|
|
|
try
|
|
{
|
|
var importer = new 領據匯入();
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
importer.Connection = conn;
|
|
|
|
// 讀取資料列表
|
|
var items = importer.ReadRows<領據匯入Item>(filePath, 1);
|
|
|
|
if (items.Count == 0)
|
|
{
|
|
return ServiceResponse.CreateError("沒有可匯入的資料");
|
|
}
|
|
|
|
// 逐筆插入資料
|
|
int successCount = 0;
|
|
int failCount = 0;
|
|
List<string> failedRows = new List<string>();
|
|
|
|
for (int i = 0; i < items.Count; i++)
|
|
{
|
|
try
|
|
{
|
|
importer.InsertOne<領據匯入Item>(items[i]);
|
|
successCount++;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
failCount++;
|
|
string errorMsg = importer.ImportRowErrorMessage<領據匯入Item>(items[i], ex.Message);
|
|
failedRows.Add($"第 {i + 2} 列:{errorMsg}");
|
|
}
|
|
}
|
|
|
|
// 清除 Session
|
|
HttpContext.Current.Session["ImportFilePath"] = null;
|
|
|
|
// 刪除臨時檔案
|
|
if (System.IO.File.Exists(filePath))
|
|
System.IO.File.Delete(filePath);
|
|
|
|
return ServiceResponse.CreateSuccess("匯入完成", new
|
|
{
|
|
successCount = successCount,
|
|
failCount = failCount,
|
|
failedRows = failedRows,
|
|
totalCount = items.Count
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// 清除臨時檔案
|
|
if (System.IO.File.Exists(filePath))
|
|
System.IO.File.Delete(filePath);
|
|
|
|
return ServiceResponse.CreateError($"匯入過程中發生錯誤:{ex.Message}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"匯入失敗:{ex.Message}");
|
|
}
|
|
}
|
|
|
|
[WebMethod(EnableSession = true)]
|
|
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
|
public ServiceResponse DownloadImportTemplate()
|
|
{
|
|
try
|
|
{
|
|
var report = new 領據匯出();
|
|
report.範本 = true;
|
|
|
|
// 查詢活動類別片語清單,填入儲存格註釋
|
|
using (var conn = DAC.NewConnection())
|
|
{
|
|
var daoPhrase = new DAC_片語(conn);
|
|
var phrases = daoPhrase.SelectBy適用欄位("活動類別");
|
|
if (phrases.Count > 0)
|
|
{
|
|
var 活動類別Comment = string.Join("\n", phrases.Select(p => p.片語內容).ToArray());
|
|
var col = report.Columns.FirstOrDefault(x => x.Key == "活動類別");
|
|
if (col != null) col.Comment = 活動類別Comment;
|
|
}
|
|
|
|
// 查詢單位別下拉選單,填入儲存格註釋(排除「請選擇」)
|
|
var 單位別List = 單位別.InputSelectList;
|
|
if (單位別List != null && 單位別List.Count > 0)
|
|
{
|
|
var 單位Comment = string.Join("\n", 單位別List.Where(x => !string.IsNullOrEmpty(x.Value.ToString())).Select(x => x.Name).ToArray());
|
|
var col = report.Columns.FirstOrDefault(x => x.Key == "單位");
|
|
if (col != null) col.Comment = 單位Comment;
|
|
}
|
|
}
|
|
|
|
var ms = report.DoReport();
|
|
|
|
// 轉換為 Base64 編碼
|
|
string excelBase64 = Convert.ToBase64String(ms.ToArray());
|
|
|
|
return ServiceResponse.CreateSuccess("下載成功", new
|
|
{
|
|
excelData = excelBase64,
|
|
fileName = "領據資料匯入格式.xlsx"
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ServiceResponse.CreateError($"下載失敗:{ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
[Serializable]
|
|
public class 領據處理Dropdowns
|
|
{
|
|
public NameValueList 身分別 { get; set; }
|
|
public NameValueList 憑證類別 { get; set; }
|
|
public NameValueList 付款方式 { get; set; }
|
|
public NameValueList 扣繳類別 { get; set; }
|
|
public NameValueList 勞務費_費用別 { get; set; }
|
|
public NameValueList 差旅費_費用別 { get; set; }
|
|
public NameValueList 單位別 { get; set; }
|
|
}
|
|
|
|
public class PrintData
|
|
{
|
|
public 領據Item Main { get; set; }
|
|
public 講師 講師 { get; set; }
|
|
public 非講師Item 非講師 { get; set; }
|
|
public 勞務費Item Labor { get; set; }
|
|
public 差旅費Item Travel { get; set; }
|
|
}
|
|
}
|