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.Configuration; namespace NP.Base.Popbill { public class PopbillService { #region 세금계산서 mgtKey(문서번호) 생성 /// /// 세금계산서 mgtKey(문서번호) 생성 /// /// CommonDao /// 발행일 /// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁 /// mgtKey public static string MakeMgtKey(CommonDao Dao, DateTime writeDate, MgtKeyType keyType = MgtKeyType.SELL) { int no = 1; var payTax = Dao.Get("cr.paytax.formgtkey", new Hashtable() { { "writeDate", writeDate } }).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; } } string 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}"; } --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.udt.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 = payItem.payoktime.Value.ToString("yyyyMMdd"); // 거래일자 detail.itemName = payItem.itemname; // 품목명 detail.spec = ""; // 규격 detail.qty = payItem.pcnt.ToString(); // 수량 detail.unitCost = payItem.payamt.ToString(); // 단가 detail.supplyCost = payItem.payamt.ToString(); // 공급가액 detail.tax = "0"; // 세액 detail.remark = ""; // 비고 taxinvoice.detailList.Add(detail); ++serialNum; } } #endregion return taxinvoice; } #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 /// payItems /// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁 /// mgtkey /// 작성된 세금계산서 데이터를 팝빌에 저장합니다. public static Result TempSave(PayTax payTax, IList payItems, MgtKeyType keyType = MgtKeyType.SELL) { Result result = new Result(); try { Response response; var taxinvoice = GetTaxinvoice(payTax, payItems).Data; if (PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, keyType, payTax.mgtkey)) { response = PopbillConfig.taxinvoiceService.Update(PopbillConfig.CorpNum, keyType, payTax.mgtkey, taxinvoice, PopbillConfig.UserID); } else { response = PopbillConfig.taxinvoiceService.Register(PopbillConfig.CorpNum, taxinvoice); } result.Data = payTax.mgtkey; result.Code = response.code; result.Message = response.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 세금계산서 삭제 /// /// 세금계산서 삭제 (국세청으로 전송되지 않은 세금계산서를 삭제합니다.) /// /// 파트너가 할당한 문서번호 /// 세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁 /// IssueResponse /// 국세청으로 전송되지 않은 세금계산서를 삭제합니다. public static Result Delete(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL) { Result result = new Result(); try { result.Data = PopbillConfig.taxinvoiceService.Delete(PopbillConfig.CorpNum, keyType, mgtkey); 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 세금계산서 즉시 발행 /// /// 세금계산서 즉시 발행 /// /// payTax /// payItems /// 지연발행 가능여부 /// 메모 /// IssueResponse /// 작성된 세금계산서 데이터를 팝빌에 저장과 동시에 발행(전자서명)하여 "발행완료" 상태로 처리합니다. public static Result RegistIssue(PayTax payTax, IList payItems, bool forceIssue = false, string memo = "") { Result result = new Result(); ; try { var taxinvoice = GetTaxinvoice(payTax, payItems).Data; 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; } }