using NP.Base;
using NP.Dao;
using NP.Model;
using Popbill;
using Popbill.Taxinvoice;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Configuration;
namespace NP.Base.Popbill
{
public class PopbillService
{
#region 세금계산서 mgtKey(문서번호) 사용여부
///
/// 세금계산서 mgtKey(문서번호) 사용여부
///
/// mgtkey
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// bool
public static Result CheckMgtKeyInUse(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL)
{
Result result = new Result();
try
{
result.IsUse = PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, keyType, mgtkey);
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 mgtKey(문서번호) 생성
///
/// 세금계산서 mgtKey(문서번호) 생성
///
/// CommonDao
/// PayTax.taxno
/// 발행일
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// mgtKey
public static string MakeMgtKey(CommonDao Dao, long taxno, DateTime writeDate, MgtKeyType keyType = MgtKeyType.SELL)
{
int no = 1;
string mgtkey = string.Empty;
var nowPayTax = Dao.Get("cr.paytaxes", new Hashtable() { { "taxno", taxno } }).FirstOrDefault();
//이미 mgtkey 발급되어 있으면 발급된 mgtkey 사용
if (nowPayTax != null && !string.IsNullOrEmpty(nowPayTax.mgtkey))
{
mgtkey = nowPayTax.mgtkey;
}
else
{
var payTax = Dao.Get("cr.paytax.formgtkey", new Hashtable() { { "writeDate", writeDate.ToString("yyyy-MM-dd") } }).FirstOrDefault();
if (payTax != null && !string.IsNullOrEmpty(payTax.mgtkey))
{
var strNo = payTax.mgtkey.Substring(payTax.mgtkey.IndexOf("L") + 1);
if (int.TryParse(strNo, out no))
{
++no;
}
}
mgtkey = $"{writeDate:yyyy-MM-dd}-L{no:D5}";
bool isUse = true;
int checkLimit = 50;
while (isUse && checkLimit > 0)
{
isUse = PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, keyType, mgtkey);
if (isUse)
{
++no;
mgtkey = $"{writeDate:yyyy-MM-dd}-L{no:D5}";
}
else
{
break;
}
--checkLimit;
}
}
return mgtkey;
}
#endregion
#region 세금계산서 Taxinvoice 생성
///
/// 세금계산서 Taxinvoice 생성
///
/// Taxinvoice
/// PayTax
/// payItems
/// Taxinvoice
public static Taxinvoice MakeTaxinvoice(Taxinvoice taxinvoice, PayTax payTax, IList payItems)
{
taxinvoice.issueType = "정발행"; //"정발행" / "역발행" / "위수탁" 중 택 1
taxinvoice.taxType = "면세"; //"과세" / "영세" / "면세" 중 택 1
taxinvoice.chargeDirection = "정과금"; //"정과금" / "역과금" 중 택 1
taxinvoice.writeDate = payTax.taxdate?.ToString("yyyyMMdd");
taxinvoice.purposeType = payTax.isreceipt == 0 ? "청구" : "영수"; //0:청구, 1:영수 {"영수" / "청구" / "없음" 중 택 1}
taxinvoice.supplyCostTotal = payTax.taxamt.ToString();
taxinvoice.taxTotal = "0";
taxinvoice.totalAmount = payTax.taxamt.ToString();
taxinvoice.invoiceeType = "사업자";
taxinvoice.invoiceeCorpNum = payTax.brno;
taxinvoice.invoiceeCorpName = payTax.asname;
taxinvoice.invoiceeCEOName = payTax.ceoname;
taxinvoice.invoiceeAddr = payTax.asaddr;
taxinvoice.invoiceeBizType = payTax.btype;
taxinvoice.invoiceeBizClass = payTax.bkind;
taxinvoice.invoiceeContactName1 = payTax.manname;
taxinvoice.invoiceeTEL1 = payTax.telno;
taxinvoice.invoiceeEmail1 = payTax.email;
//taxinvoice.serialNum = payTax.taxno.ToString();
#region 상세항목(품목) 정보
if (payItems != null)
{
/**************************************************************************
* 상세항목(품목) 정보 *
* - 상세항목 정보는 세금계산서 필수기재사항이 아니므로 작성하지 않더라도 *
* 세금계산서 발행이 가능합니다. *
* - 최대 99건까지 작성가능 *
**************************************************************************/
taxinvoice.detailList = new List();
var serialNum = 1;
foreach (var payItem in payItems)
{
TaxinvoiceDetail detail = new TaxinvoiceDetail();
detail.serialNum = serialNum; // 일련번호, 1부터 순차기재
detail.purchaseDT = payTax.taxdate?.ToString("yyyyMMdd"); // 거래일자
detail.itemName = payItem.itemname; // 품목명
detail.spec = payItem.username; // 규격(이름)
detail.qty = payItem.pcnt.ToString(); // 수량
detail.unitCost = payItem.payamt.ToString(); // 단가
detail.supplyCost = payItem.payamt.ToString(); // 공급가액
detail.tax = "0"; // 세액
detail.remark = payTax.taxinfo; // 비고
taxinvoice.detailList.Add(detail);
++serialNum;
}
}
#endregion
return taxinvoice;
}
#endregion
#region 세금계산서 상태
///
/// 세금계산서 상태
///
/// 상태코드
/// 상태
public static string GetTaxinvoiceState(int stateCode)
{
string state = string.Empty;
switch (stateCode)
{
case 100:
state = "임시저장";
break;
case 300:
state = "발행완료";
break;
case 301:
state = "국세청-전송전";
break;
case 302:
state = "국세청-전송대기";
break;
case 303:
state = "국세청-전송중";
break;
case 304:
state = "국세청-전송성공";
break;
case 305:
state = "국세청-전송실패";
break;
case 600:
state = "발행취소";
break;
default:
state = $"stateCode:{stateCode}";
break;
}
return state;
}
#endregion
#region 세금계산서 상세정보
///
/// 세금계산서 상세정보
///
/// PayTax
/// payItems
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// Taxinvoice
public static Result GetTaxinvoice(PayTax payTax, IList payItems = null, MgtKeyType keyType = MgtKeyType.SELL)
{
Result result = new Result();
try
{
if (!string.IsNullOrEmpty(payTax.mgtkey) && PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, keyType, payTax.mgtkey))
{
result.Data = PopbillConfig.taxinvoiceService.GetDetailInfo(PopbillConfig.CorpNum, keyType, payTax.mgtkey);
}
else
{
CorpInfo corpInfo = PopbillConfig.taxinvoiceService.GetCorpInfo(PopbillConfig.CorpNum, PopbillConfig.UserID);
Contact contact = PopbillConfig.taxinvoiceService.ListContact(PopbillConfig.CorpNum, PopbillConfig.UserID).Where(w => w.mgrYN == true).FirstOrDefault();
result.Data = new Taxinvoice
{
invoicerAddr = corpInfo?.addr,
invoicerCEOName = corpInfo?.ceoname,
invoicerCorpName = corpInfo?.corpName,
invoicerMgtKey = payTax.mgtkey,
invoicerCorpNum = PopbillConfig.CorpNum,
invoicerBizClass = corpInfo?.bizClass,
invoicerBizType = corpInfo?.bizType,
invoicerContactName = contact?.personName,
invoicerEmail = contact?.email,
invoicerHP = contact?.hp,
invoicerTEL = contact?.tel
};
}
result.Data = MakeTaxinvoice(result.Data, payTax, payItems);
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 상태정보
///
/// 세금계산서 상태정보
///
/// PayTax
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// Taxinvoice
public static Result GetTaxinvoiceInfo(PayTax payTax, MgtKeyType keyType = MgtKeyType.SELL)
{
Result result = new Result();
try
{
result.Data = PopbillConfig.taxinvoiceService.GetInfo(PopbillConfig.CorpNum, keyType, payTax.mgtkey);
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 파일등록(사업자등록증)
///
/// 세금계산서 파일등록(사업자등록증)
///
///
///
///
///
public static Response AttachFile(CommonDao Dao, PayTax payTax, MgtKeyType keyType = MgtKeyType.SELL)
{
Response response = new Response();
if (payTax.fgno != null && payTax.fgno != 0)
{
IList files = Dao.GetFiles(payTax.fgno.Value);
#region 기존 등록된 파일삭제(사업자등록증)
if (files.Count > 0)
{
var attachedFiles = PopbillConfig.taxinvoiceService.GetFiles(PopbillConfig.CorpNum, keyType, payTax.mgtkey);
foreach (var attachedFile in attachedFiles)
{
response = PopbillConfig.taxinvoiceService.DeleteFile(PopbillConfig.CorpNum, keyType, payTax.mgtkey, attachedFile.attachedFile, PopbillConfig.UserID);
}
}
#endregion
#region #region 파일등록(사업자등록증)
foreach (var file in files)
{
var filePath = HttpContext.Current.Server.MapPath(file.fullurl);
if (System.IO.File.Exists(filePath))
{
response = PopbillConfig.taxinvoiceService.AttachFile(PopbillConfig.CorpNum, keyType, payTax.mgtkey, filePath, PopbillConfig.UserID);
}
}
#endregion
}
return response;
}
#endregion
#region 세금계산서 임시저장(수정)
///
/// 세금계산서 임시저장(수정)
///
/// CommonDao
/// payTax
/// payItems
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// mgtkey
/// 작성된 세금계산서 데이터를 팝빌에 저장합니다.
public static Result TempSave(CommonDao Dao, PayTax payTax, IList payItems, MgtKeyType keyType = MgtKeyType.SELL)
{
Result result = new Result();
try
{
var taxinvoice = GetTaxinvoice(payTax, payItems).Data;
if (PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, keyType, payTax.mgtkey))
{
result.Data = PopbillConfig.taxinvoiceService.Update(PopbillConfig.CorpNum, keyType, payTax.mgtkey, taxinvoice, PopbillConfig.UserID);
}
else
{
result.Data = PopbillConfig.taxinvoiceService.Register(PopbillConfig.CorpNum, taxinvoice);
}
if (result.Data.code == 1)
{
AttachFile(Dao, payTax, keyType);
}
result.Code = result.Data.code;
result.Message = result.Data.message;
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 발행
///
/// 세금계산서 발행
///
/// 파트너가 할당한 문서번호
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// 지연발행 가능여부
/// 메모
/// IssueResponse
/// "임시저장" 또는 "(역)발행대기" 상태의 세금계산서를 발행(전자서명)하며, "발행완료" 상태로 처리합니다
public static Result Issue(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL, bool forceIssue = false, string memo = "")
{
Result result = new Result();
try
{
result.Data = PopbillConfig.taxinvoiceService.Issue(PopbillConfig.CorpNum, keyType, mgtkey, memo, forceIssue, PopbillConfig.UserID);
result.Code = result.Data.code;
result.Message = result.Data.message;
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 발행취소
///
/// 세금계산서 발행취소
///
/// 파트너가 할당한 문서번호
/// 메모
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// IssueResponse
/// 국세청 전송 이전 "발행완료" 상태의 전자세금계산서를 "발행취소"하고, 해당 건은 국세청 신고 대상에서 제외됩니다.
public static Result CancelIssue(string mgtkey, string memo = "", MgtKeyType keyType = MgtKeyType.SELL)
{
Result result = new Result();
try
{
result.Data = PopbillConfig.taxinvoiceService.CancelIssue(PopbillConfig.CorpNum, keyType, mgtkey, memo, PopbillConfig.UserID);
result.Code = result.Data.code;
result.Message = result.Data.message;
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 즉시 발행
///
/// 세금계산서 즉시 발행
///
/// Dao
/// payTax
/// payItems
/// 지연발행 가능여부
/// 메모
/// IssueResponse
/// 작성된 세금계산서 데이터를 팝빌에 저장과 동시에 발행(전자서명)하여 "발행완료" 상태로 처리합니다.
public static Result RegistIssue(CommonDao Dao, PayTax payTax, IList payItems, string managerPhone = "", string managerName = "", MgtKeyType keyType = MgtKeyType.SELL, bool forceIssue = false, string memo = "")
{
Result result = new Result(); ;
try
{
//첨부파일이 있으면 임시저장 후 발행
if (payTax.fgno != null && payTax.fgno != 0)
{
var resultResponse = TempSave(Dao, payTax, payItems, keyType);
if (resultResponse.IsSuccess)
{
result = Issue(payTax.mgtkey, keyType, forceIssue, memo);
}
else
{
result.IsSuccess = false;
result.Code = resultResponse.Code;
result.Message = resultResponse.Message;
}
}
else
{
var taxinvoice = GetTaxinvoice(payTax, payItems, keyType).Data;
taxinvoice.invoicerTEL = managerPhone; // 세금계산서 발행시 invoicerTEL번호를 기업에 등록된 연락처로 변경 2023.05.17 (pms: 7903)
taxinvoice.invoicerContactName = managerName;// 세금계산서 발행시 invoicerTEL번호를 기업에 등록된 연락처로 변경 2023.05.17 (pms: 7903)
result.Data = PopbillConfig.taxinvoiceService.RegistIssue(PopbillConfig.CorpNum, taxinvoice, forceIssue, memo);
result.Code = result.Data.code;
result.Message = result.Data.message;
}
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 인쇄 팝업 URL 확인
///
/// 세금계산서 인쇄 팝업 URL 확인
///
/// 파트너가 할당한 문서번호
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// URL
public static Result GetPrintURL(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL)
{
Result result = new Result(); ;
try
{
result.Data = PopbillConfig.taxinvoiceService.GetPrintURL(PopbillConfig.CorpNum, keyType, mgtkey, PopbillConfig.UserID);
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
#region 세금계산서 인쇄 팝업 URL 확인 - 공급받는자용
///
/// 세금계산서 인쇄 팝업 URL 확인 - 공급받는자용
///
/// 파트너가 할당한 문서번호
/// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁
/// URL
public static Result GetEPrintURL(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL)
{
Result result = new Result(); ;
try
{
result.Data = PopbillConfig.taxinvoiceService.GetEPrintURL(PopbillConfig.CorpNum, keyType, mgtkey, PopbillConfig.UserID);
}
catch (PopbillException ex)
{
result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
#endregion
}
public class Result
{
public bool IsSuccess = true;
public long Code = 1;
public String Message = string.Empty;
public T Data;
public bool IsUse = false;
}
}