팝빌 세금계산서 연동 작업

This commit is contained in:
lch 2021-04-26 09:19:17 +00:00
parent 499f80d531
commit 22a9c1ac90
6 changed files with 534 additions and 230 deletions

View File

@ -795,16 +795,14 @@ namespace NP.BO.Controllers
vm.PayTaxItem = Dao.Get<PayItem>("cr.paytaxitem2", new System.Collections.Hashtable() { { "taxno", vm.longval } }); vm.PayTaxItem = Dao.Get<PayItem>("cr.paytaxitem2", new System.Collections.Hashtable() { { "taxno", vm.longval } });
#region Popbill #region Popbill
var mgtkey = vm.PayTaxes.First()?.mgtkey; var payTax = vm.PayTaxes.First();
if (!string.IsNullOrEmpty(mgtkey)) if (payTax != null)
{ {
ViewBag.Taxinvoice = PopbillService.GetTaxinvoice(mgtkey).Data; var result = PopbillService.GetTaxinvoice(payTax);
if (result.IsSuccess)
{
ViewBag.Taxinvoice = result.Data;
} }
else
{
var taxdate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
mgtkey = PopbillService.MakeMgtKey(Dao, taxdate, MgtKeyType.SELL).Data;
ViewBag.Taxinvoice = PopbillService.GetTaxinvoiceR(mgtkey).Data;
} }
#endregion #endregion

View File

@ -109,33 +109,33 @@
<tbody> <tbody>
<tr> <tr>
<th>회사명</th> <th>회사명</th>
<td><input type="text" class="form-control dev" name="invoicerCorpName" value="@taxinvoice.invoicerCorpName" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerCorpName" readonly value="@taxinvoice.invoicerCorpName" /></td>
<th>대표자</th> <th>대표자</th>
<td><input type="text" class="form-control dev" name="invoicerCEOName" value="@taxinvoice.invoicerCEOName" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerCEOName" readonly value="@taxinvoice.invoicerCEOName" /></td>
</tr> </tr>
<tr> <tr>
<th>사업자등록번호</th> <th>사업자등록번호</th>
<td><input type="text" class="form-control dev" name="invoicerCorpNum" value="@taxinvoice.invoicerCorpNum" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerCorpNum" readonly value="@taxinvoice.invoicerCorpNum" /></td>
<th>업태</th> <th>업태</th>
<td><input type="text" class="form-control dev" name="invoicerBizType" value="@taxinvoice.invoicerBizType" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerBizType" readonly value="@taxinvoice.invoicerBizType" /></td>
</tr> </tr>
<tr> <tr>
<th>종목</th> <th>종목</th>
<td><input type="text" class="form-control dev" name="invoicerBizClass" value="@taxinvoice.invoicerBizClass" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerBizClass" readonly value="@taxinvoice.invoicerBizClass" /></td>
<th>사업장주소</th> <th>사업장주소</th>
<td><input type="text" class="form-control dev" name="invoicerAddr" value="@taxinvoice.invoicerAddr" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerAddr" readonly value="@taxinvoice.invoicerAddr" /></td>
</tr> </tr>
<tr> <tr>
<th>담당자</th> <th>담당자</th>
<td><input type="text" class="form-control dev" name="invoicerContactName" value="@taxinvoice.invoicerContactName" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerContactName" readonly value="@taxinvoice.invoicerContactName" /></td>
<th>연락처</th> <th>연락처</th>
<td><input type="text" class="form-control dev" name="invoicerTEL" value="@taxinvoice.invoicerTEL" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerTEL" readonly value="@taxinvoice.invoicerTEL" /></td>
</tr> </tr>
<tr> <tr>
<th>이메일주소</th> <th>이메일주소</th>
<td><input type="text" class="form-control dev" name="invoicerEmail" value="@taxinvoice.invoicerEmail" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerEmail" readonly value="@taxinvoice.invoicerEmail" /></td>
<th>문서번호</th> <th>문서번호</th>
<td><input type="text" class="form-control dev" name="invoiceeMgtKey" value="@taxinvoice.invoicerMgtKey" /></td> <td><input type="text" class="form-control dev" name="taxinvoice.invoicerMgtKey" readonly value="@taxinvoice.invoicerMgtKey" /></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -175,8 +175,6 @@
<th style="background-color: #ffef98">발행일</th> <th style="background-color: #ffef98">발행일</th>
<td> <td>
<input type="text" data-date-format="yyyy-mm-dd" class="form-control dev refundtime input-sm input-s datepicker-input form-control dev " name="taxdate" value="@(t.taxdate==null?"":t.taxdate.Value.ToString("yyyy-MM-dd"))" /> <input type="text" data-date-format="yyyy-mm-dd" class="form-control dev refundtime input-sm input-s datepicker-input form-control dev " name="taxdate" value="@(t.taxdate==null?"":t.taxdate.Value.ToString("yyyy-MM-dd"))" />
<input type="hidden" class="form-control dev" name="iscancel" value="@t.iscancel" />
<label style="display:none;"><input type="checkbox" id="iscanceled" /> 발행취소</label>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -196,7 +194,10 @@
</tr> </tr>
<tr> <tr>
<th>영수구분</th> <th>영수구분</th>
<td colspan="3">@(t.isreceipt == 0 ? "청구" : "영수")</td> <td colspan="3">
<label><input type="radio" name="isreceipt" value="0" @(t.isreceipt == 0 ? "checked" : "") disabled style="vertical-align: bottom" /> 청구</label>
<label><input type="radio" name="isreceipt" value="1" @(t.isreceipt == 0 ? "" : "checked") disabled style="vertical-align: bottom" /> 영수</label>
</td>
</tr> </tr>
<tr> <tr>
<th>기재사항</th> <th>기재사항</th>
@ -209,26 +210,35 @@
<input type="hidden" name="payno" value="@t.payno" /> <input type="hidden" name="payno" value="@t.payno" />
<input type="hidden" name="cno" value="@t.cno" /> <input type="hidden" name="cno" value="@t.cno" />
<input type="hidden" name="mgtkey" value="@t.mgtkey" /> <input type="hidden" name="mgtkey" value="@t.mgtkey" />
<input type="hidden" name="iscancel" value="@t.iscancel" />
<input type="hidden" name="taxamt" value="@t.taxamt" />
<div class="text-center"> <div class="text-center">
<a href="#" class="btn btn-primary" onclick="save();">저장</a> @if (t.iscancel == null || t.iscancel.Value != 1)
@if (string.IsNullOrEmpty(t.mgtkey))
{ {
<a href="#" class="btn btn-success" onclick="register();">임시저장 및 미리보기</a>
if (string.IsNullOrEmpty(t.mgtkey))
{
<a href="#" class="btn btn-primary" onclick="save();">저장</a>
<a href="#" class="btn btn-success" onclick="tempsave();">임시저장</a>
<a href="#" class="btn btn-success" onclick="registIssue();">계산서 즉시발행</a> <a href="#" class="btn btn-success" onclick="registIssue();">계산서 즉시발행</a>
<a href="#" class="btn btn-danger" onclick="cancelIssue();">발행취소</a>
} }
else else
{ {
if (string.IsNullOrEmpty(taxinvoice.ntsconfirmNum)) if (string.IsNullOrEmpty(taxinvoice.ntsconfirmNum))
{ {
<a href="#" class="btn btn-success" onclick="register();">임시저장 및 미리보기</a> <a href="#" class="btn btn-primary" onclick="save();">저장</a>
<a href="#" class="btn btn-success" onclick="registIssue();">계산서 즉시발행</a> <a href="#" class="btn btn-success" onclick="tempsave();">임시저장</a>
<a href="#" class="btn btn-success" onclick="view();">미리보기</a>
<a href="#" class="btn btn-success" onclick="Issue();">계산서 즉시발행</a>
<a href="#" class="btn btn-danger" onclick="cancelIssue();">발행취소</a>
} }
else else
{ {
<a href="#" class="btn btn-success" onclick="view();">계산서조회</a> <a href="#" class="btn btn-success" onclick="view();">계산서조회</a>
} }
} }
<a href="#" class="btn btn-danger" onclick="cancelIssue();">발행취소</a> }
<a href="#" class="btn btn-default" onclick="$('#dform').attr('action', '/croom/tax');golist();">목록</a> <a href="#" class="btn btn-default" onclick="$('#dform').attr('action', '/croom/tax');golist();">목록</a>
</div> </div>
@Html.Partial("./Partial/dform", Model) @Html.Partial("./Partial/dform", Model)
@ -273,17 +283,12 @@
@section scripts{ @section scripts{
<script> <script>
$(document).ready(function () { $(document).ready(function () {
if ('@(t.iscancel)' == '1') {
$("input:checkbox[id='iscanceled']").prop("checked", true);
} else {
$("input:checkbox[id='iscanceled']").prop("checked", false);
}
}); });
function gotab() { function gotab() {
$("#dform").attr("action", "/croom/taxsmart").submit(); $("#dform").attr("action", "/croom/taxsmart").submit();
} }
function save() { function save() {
$("input[name=iscancel]").val($("input:checkbox[id='iscanceled']").prop("checked") ? 1 : 0);
cap("/acommon/paytaxsave", "sform", "cbsave"); cap("/acommon/paytaxsave", "sform", "cbsave");
} }
function cbsave() { function cbsave() {
@ -291,24 +296,95 @@
msg("저장되었습니다.", null, null, null, null, "bglayer();rfs(0,'sform');"); msg("저장되었습니다.", null, null, null, null, "bglayer();rfs(0,'sform');");
} else if (capResult.code == -1) { } else if (capResult.code == -1) {
msg("이미 발행요청건이 존재합니다."); msg("이미 발행요청건이 존재합니다.");
} } else {
else {
msgadmin(); msgadmin();
} }
} }
function tempsave() {
function register() { cap("/acommon/paytaxtempsave", "sform", "cbtempsave");
}
function cbtempsave() {
if (capResult.code == 1000) {
msg("임시저장되었습니다.", null, null, null, null, "bglayer();rfs(0,'sform');");
} else if (capResult.code == -1) {
msg("이미 발행요청건이 존재합니다.");
} else {
if (capResult.msg != "") {
msg(capResult.msg);
} else {
msgadmin();
} }
function view() {
} }
function registIssue() {
} }
function cancelIssue() { function cancelIssue() {
if (confirm("발행을 취소하시겠습니까?")) {
$("input[name='iscancel']").val(1);
cap("/acommon/paytaxcancelissue", "sform", "cbcancelIssue");
}
}
function cbcancelIssue() {
if (capResult.code == 1000) {
msg("발행취소되었습니다.", null, null, null, null, "bglayer();rfs(0,'sform');");
} else {
if (capResult.msg != "") {
msg(capResult.msg);
} else {
msgadmin();
}
}
}
function Issue() {
if (confirm("입력된 내용으로 계산서 발행을 진행하시겠습니까?")) {
cap("/acommon/paytaxissue", "sform", "cbIssue");
}
}
function cbIssue() {
if (capResult.code == 1000) {
msg("발행되었습니다.", null, null, null, null, "bglayer();rfs(0,'sform');");
} else if (capResult.code == -1) {
msg("이미 발행요청건이 존재합니다.");
} else {
if (capResult.msg != "") {
msg(capResult.msg);
} else {
msgadmin();
}
}
}
function registIssue() {
if (confirm("입력된 내용으로 계산서 발행을 진행하시겠습니까?")) {
cap("/acommon/paytaxregistissue", "sform", "cbregistIssue");
}
}
function cbregistIssue() {
if (capResult.code == 1000) {
msg("즉시발행되었습니다.", null, null, null, null, "bglayer();rfs(0,'sform');");
} else if (capResult.code == -1) {
msg("이미 발행요청건이 존재합니다.");
} else {
if (capResult.msg != "") {
msg(capResult.msg);
} else {
msgadmin();
}
}
}
function view() {
cap("/acommon/paytaxview", "sform", "cbview");
}
function cbview() {
if (capResult.code == 1000) {
var pop = window.open(capResult.obj, "taxprint", "width=900, height=720, scrollbars=yes, resizable=yes, status=no, location=no, left=0, top=0");
if (pop == null) {
msg("팝업이 차단되어 있습니다. 차단을 해제해 주세요.");
}
} else {
if (capResult.msg != "") {
msg(capResult.msg);
} else {
msgadmin();
}
}
} }
</script> </script>
} }

View File

@ -773,66 +773,193 @@ namespace NP.Base.Controllers
} }
return JsonOK(Dao.Save("cr.paytax.save", d)); return JsonOK(Dao.Save("cr.paytax.save", d));
} }
#region ( paytax.mgtkey )
/// <summary> /// <summary>
/// 팝빌 임시저장 및 미리보기(팝빌 임시저장 및 paytax.mgtkey 업데이트 후 세금계산서 인쇄 url 리턴) /// 세금계산서 임시저장(팝빌 임시저장 및 paytax.mgtkey 업데이트)
/// </summary> /// </summary>
/// <param name="d"></param> /// <param name="payTax">payTax</param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public JsonResult PayTaxRegister(PayTax d) public JsonResult PayTaxTempSave(PayTax payTax)
{ {
d.uno = SUserInfo.UserNo; d.uip = GetUserIP(); payTax.uno = SUserInfo.UserNo; payTax.uip = GetUserIP();
if (d.iscancel != 1 && Dao.Get<PayTax>("cr.paytaxes", new Hashtable() { { "payno", d.payno }, { "cno", d.cno }, { "iscancel", 0 }, { "nottaxno", d.taxno } }).Count() > 0) if (payTax.iscancel != 1 && Dao.Get<PayTax>("cr.paytaxes", new Hashtable() { { "payno", payTax.payno }, { "cno", payTax.cno }, { "iscancel", 0 }, { "nottaxno", payTax.taxno } }).Count() > 0)
{ {
return JsonBack(new JsonRtn() { code = -1 }); return JsonBack(new JsonRtn() { code = -1 });
} }
return JsonOK(Dao.Save("cr.paytax.save", d));
payTax.udt = DateTime.Now;
if (string.IsNullOrEmpty(payTax.mgtkey))
{
payTax.mgtkey = Popbill.PopbillService.MakeMgtKey(Dao, payTax.udt);
} }
if (Dao.Save("cr.paytax.save", payTax) > 0)
{
var payItems = Dao.Get<PayItem>("cr.paytaxitem2", new System.Collections.Hashtable() { { "taxno", payTax.taxno } });
var result = Popbill.PopbillService.TempSave(payTax, payItems);
if (result.IsSuccess)
{
return JsonOK(result.Code);
}
else
{
return JsonError(JSONCode.Error, result.Message, result);
}
}
return JsonOK(0);
}
#endregion
#region ( paytax.taxdate )
/// <summary> /// <summary>
/// 계산서 즉시발행(팝빌 발행 및 paytax.taxdate ,paytax.mgtkey 업데이트) /// 세금계산서 발행(팝빌 발행 및 paytax.taxdate 업데이트)
/// </summary> /// </summary>
/// <param name="d"></param> /// <param name="payTax"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public JsonResult PayTaxRegistIssue(PayTax d) public JsonResult PayTaxIssue(PayTax payTax)
{ {
d.uno = SUserInfo.UserNo; d.uip = GetUserIP(); payTax.uno = SUserInfo.UserNo; payTax.uip = GetUserIP();
if (d.iscancel != 1 && Dao.Get<PayTax>("cr.paytaxes", new Hashtable() { { "payno", d.payno }, { "cno", d.cno }, { "iscancel", 0 }, { "nottaxno", d.taxno } }).Count() > 0) if (payTax.iscancel != 1 && Dao.Get<PayTax>("cr.paytaxes", new Hashtable() { { "payno", payTax.payno }, { "cno", payTax.cno }, { "iscancel", 0 }, { "nottaxno", payTax.taxno } }).Count() > 0)
{ {
return JsonBack(new JsonRtn() { code = -1 }); return JsonBack(new JsonRtn() { code = -1 });
} }
return JsonOK(Dao.Save("cr.paytax.save", d));
if (payTax.taxdate == null)
{
payTax.taxdate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
} }
if (Dao.Save("cr.paytax.save", payTax) > 0)
{
var result = Popbill.PopbillService.Issue(payTax.mgtkey);
if (result.IsSuccess)
{
return JsonOK(result.Code);
}
else
{
return JsonError(JSONCode.Error, result.Message, result);
}
}
return JsonOK(0);
}
#endregion
#region ( paytax.taxdate ,paytax.mgtkey )
/// <summary> /// <summary>
/// 발행취소(발행전: paytax.iscancel 상태값 변경, 발행완료: 팝빌 발행취소 및 paytax.iscancel 상태값 변경) /// 세금계산서 즉시발행(팝빌 발행 및 paytax.taxdate ,paytax.mgtkey 업데이트)
/// </summary> /// </summary>
/// <param name="d"></param> /// <param name="payTax">payTax</param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public JsonResult PayTaxCancelIssue(PayTax d) public JsonResult PayTaxRegistIssue(PayTax payTax)
{ {
d.uno = SUserInfo.UserNo; d.uip = GetUserIP(); payTax.uno = SUserInfo.UserNo; payTax.uip = GetUserIP();
if (d.iscancel != 1 && Dao.Get<PayTax>("cr.paytaxes", new Hashtable() { { "payno", d.payno }, { "cno", d.cno }, { "iscancel", 0 }, { "nottaxno", d.taxno } }).Count() > 0) if (payTax.iscancel != 1 && Dao.Get<PayTax>("cr.paytaxes", new Hashtable() { { "payno", payTax.payno }, { "cno", payTax.cno }, { "iscancel", 0 }, { "nottaxno", payTax.taxno } }).Count() > 0)
{ {
return JsonBack(new JsonRtn() { code = -1 }); return JsonBack(new JsonRtn() { code = -1 });
} }
return JsonOK(Dao.Save("cr.paytax.save", d));
if (payTax.taxdate == null)
{
payTax.taxdate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
} }
payTax.udt = DateTime.Now;
if (string.IsNullOrEmpty(payTax.mgtkey))
{
payTax.mgtkey = Popbill.PopbillService.MakeMgtKey(Dao, payTax.udt);
}
if (Dao.Save("cr.paytax.save", payTax) > 0)
{
var payItems = Dao.Get<PayItem>("cr.paytaxitem2", new System.Collections.Hashtable() { { "taxno", payTax.taxno } });
var result = Popbill.PopbillService.RegistIssue(payTax, payItems);
if (result.IsSuccess)
{
return JsonOK(result.Code);
}
else
{
return JsonError(JSONCode.Error, result.Message, result);
}
}
return JsonOK(0);
}
#endregion
#region (: paytax.iscancel , : paytax.iscancel )
/// <summary> /// <summary>
/// 계산서조회(팝빌 세금계산서 인쇄 url 리턴) /// 세금계산서 발행취소(발행전: paytax.iscancel 상태값 변경, 발행완료: 팝빌 발행취소 및 paytax.iscancel 상태값 변경)
/// </summary> /// </summary>
/// <param name="d"></param> /// <param name="payTax"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public JsonResult PayTaxView(PayTax d) public JsonResult PayTaxCancelIssue(PayTax payTax)
{ {
d.uno = SUserInfo.UserNo; d.uip = GetUserIP(); payTax.uno = SUserInfo.UserNo; payTax.uip = GetUserIP();
if (d.iscancel != 1 && Dao.Get<PayTax>("cr.paytaxes", new Hashtable() { { "payno", d.payno }, { "cno", d.cno }, { "iscancel", 0 }, { "nottaxno", d.taxno } }).Count() > 0) payTax.iscancel = 1;
if (!string.IsNullOrEmpty(payTax.mgtkey))
{ {
return JsonBack(new JsonRtn() { code = -1 }); var taxinvoice = Popbill.PopbillService.GetTaxinvoice(payTax).Data;
if (!string.IsNullOrEmpty(taxinvoice.ntsconfirmNum))
{
if (Dao.Save("cr.paytax.save", payTax) > 0)
{
var result = Popbill.PopbillService.CancelIssue(payTax.mgtkey);
if (result.IsSuccess)
{
return JsonOK(result.Code);
} }
return JsonOK(Dao.Save("cr.paytax.save", d)); else
{
return JsonError(JSONCode.Error, result.Message, result);
} }
}
else
{
return JsonOK(0);
}
}
else
{
return JsonOK(Dao.Save("cr.paytax.save", payTax));
}
}
else
{
return JsonOK(Dao.Save("cr.paytax.save", payTax));
}
}
#endregion
#region ( url )
/// <summary>
/// 세금계산서 조회(팝빌 세금계산서 인쇄 url 리턴)
/// </summary>
/// <param name="payTax"></param>
/// <returns></returns>
[HttpPost]
public JsonResult PayTaxView(PayTax payTax)
{
var result = Popbill.PopbillService.GetPrintURL(payTax.mgtkey);
if (result.IsSuccess)
{
return JsonObj<string>(result.Data);
}
else
{
return JsonError(JSONCode.Error, result.Message, result);
}
}
#endregion
[HttpPost] [HttpPost]
public JsonResult SmartTaxView(String csid) public JsonResult SmartTaxView(String csid)
{ {

View File

@ -56,7 +56,7 @@ namespace NP.Base.Popbill
_linkID = WebConfigurationManager.AppSettings["Popbill.LinkID"]; _linkID = WebConfigurationManager.AppSettings["Popbill.LinkID"];
_secretKey = WebConfigurationManager.AppSettings["Popbill.SecretKey"]; _secretKey = WebConfigurationManager.AppSettings["Popbill.SecretKey"];
_corpNum = WebConfigurationManager.AppSettings["Popbill.CorpNum"]; _corpNum = WebConfigurationManager.AppSettings["Popbill.CorpNum"];
_userID = WebConfigurationManager.AppSettings["Popbill.UserID"]; _userID = WebConfigurationManager.AppSettings["Popbill.UserID"] != string.Empty ? WebConfigurationManager.AppSettings["Popbill.UserID"] : null ;
// 세금계산서 서비스 객체 초기화 // 세금계산서 서비스 객체 초기화
taxinvoiceService = new TaxinvoiceService(_linkID, _secretKey); taxinvoiceService = new TaxinvoiceService(_linkID, _secretKey);

View File

@ -13,33 +13,20 @@ namespace NP.Base.Popbill
{ {
public class PopbillService public class PopbillService
{ {
#region mgtKey()
/// <summary> /// <summary>
/// 세금계산서 문서번호{mgtKey} 생성 /// 세금계산서 mgtKey(문서번호) 생성
/// </summary> /// </summary>
/// <param name="Dao">CommonDao</param> /// <param name="Dao">CommonDao</param>
/// <param name="taxdate">발행일</param> /// <param name="writeDate">발행일</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param> /// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>mgtKey</returns> /// <returns>mgtKey</returns>
public static Result<String> MakeMgtKey(CommonDao Dao, DateTime taxdate, MgtKeyType mgtKeyType = MgtKeyType.SELL) public static string MakeMgtKey(CommonDao Dao, DateTime writeDate, MgtKeyType keyType = MgtKeyType.SELL)
{ {
Result<String> result = new Result<string>();
try
{
string mgtkey = string.Empty;
int no = 1; int no = 1;
var payTax = Dao.Get<PayTax>("cr.paytax.formgtkey", new Hashtable() { { "taxdate", taxdate } }).FirstOrDefault(); var payTax = Dao.Get<PayTax>("cr.paytax.formgtkey", new Hashtable() { { "writeDate", writeDate } }).FirstOrDefault();
if (payTax == null) if (payTax != null && !string.IsNullOrEmpty(payTax.mgtkey))
{
payTax = new PayTax() { };
}
if (payTax.taxdate == null)
{
payTax.taxdate = taxdate;
}
if (!string.IsNullOrEmpty(payTax.mgtkey))
{ {
var strNo = payTax.mgtkey.Substring(payTax.mgtkey.IndexOf("L") + 1); var strNo = payTax.mgtkey.Substring(payTax.mgtkey.IndexOf("L") + 1);
@ -49,70 +36,108 @@ namespace NP.Base.Popbill
} }
} }
mgtkey = $"{taxdate:yyyy-MM-dd}-L{no:D5}"; string mgtkey = $"{writeDate:yyyy-MM-dd}-L{no:D5}";
bool isUse = true; bool isUse = true;
int checkLimit = 10; int checkLimit = 50;
while (isUse && checkLimit > 0) while (isUse && checkLimit > 0)
{ {
isUse = PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, mgtKeyType, mgtkey); isUse = PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, keyType, mgtkey);
if (isUse) if (isUse)
{ {
++no; ++no;
mgtkey = $"{taxdate:yyyy-MM-dd}-L{no:D5}"; mgtkey = $"{writeDate:yyyy-MM-dd}-L{no:D5}";
} }
--checkLimit; --checkLimit;
} }
result.Data = mgtkey;
}
catch (PopbillException ex)
{
result.Code = ex.code.ToString();
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
return mgtkey;
}
#endregion
#region Taxinvoice
/// <summary>
/// 세금계산서 Taxinvoice 생성
/// </summary>
/// <param name="taxinvoice">Taxinvoice</param>
/// <param name="payTax">PayTax</param>
/// <param name="payItems">payItems</param>
/// <returns>Taxinvoice</returns>
public static Taxinvoice MakeTaxinvoice(Taxinvoice taxinvoice, PayTax payTax, IList<PayItem> 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<TaxinvoiceDetail>();
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
/// <summary> /// <summary>
/// 세금계산서 상세정보 /// 세금계산서 상세정보
/// </summary> /// </summary>
/// <param name="mgtkey">파트너가 할당한 문서번호</param> /// <param name="payTax">PayTax</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param> /// <param name="payItems">payItems</param>
/// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>Taxinvoice</returns> /// <returns>Taxinvoice</returns>
public static Result<Taxinvoice> GetTaxinvoice(string mgtkey, MgtKeyType mgtKeyType = MgtKeyType.SELL) public static Result<Taxinvoice> GetTaxinvoice(PayTax payTax, IList<PayItem> payItems = null, MgtKeyType keyType = MgtKeyType.SELL)
{ {
Result<Taxinvoice> result = new Result<Taxinvoice>(); Result<Taxinvoice> result = new Result<Taxinvoice>();
try try
{ {
result.Data = PopbillConfig.taxinvoiceService.GetDetailInfo(PopbillConfig.CorpNum, mgtKeyType, mgtkey); if (!string.IsNullOrEmpty(payTax.mgtkey) && PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, keyType, payTax.mgtkey))
}
catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.Data = PopbillConfig.taxinvoiceService.GetDetailInfo(PopbillConfig.CorpNum, keyType, payTax.mgtkey);
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
} }
finally else
{
if (result.Data == null)
{
result.Data = new Taxinvoice() { invoicerMgtKey = mgtkey };
}
}
return result;
}
/// <summary>
/// 세금계산서 공급자정보
/// </summary>
/// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <returns>Taxinvoice</returns>
public static Result<Taxinvoice> GetTaxinvoiceR(string mgtkey)
{
Result<Taxinvoice> result = new Result<Taxinvoice>();
try
{ {
CorpInfo corpInfo = PopbillConfig.taxinvoiceService.GetCorpInfo(PopbillConfig.CorpNum, PopbillConfig.UserID); CorpInfo corpInfo = PopbillConfig.taxinvoiceService.GetCorpInfo(PopbillConfig.CorpNum, PopbillConfig.UserID);
Contact contact = PopbillConfig.taxinvoiceService.ListContact(PopbillConfig.CorpNum, PopbillConfig.UserID).Where(w => w.mgrYN == true).FirstOrDefault(); Contact contact = PopbillConfig.taxinvoiceService.ListContact(PopbillConfig.CorpNum, PopbillConfig.UserID).Where(w => w.mgrYN == true).FirstOrDefault();
@ -121,7 +146,7 @@ namespace NP.Base.Popbill
invoicerAddr = corpInfo?.addr, invoicerAddr = corpInfo?.addr,
invoicerCEOName = corpInfo?.ceoname, invoicerCEOName = corpInfo?.ceoname,
invoicerCorpName = corpInfo?.corpName, invoicerCorpName = corpInfo?.corpName,
invoicerMgtKey = mgtkey, invoicerMgtKey = payTax.mgtkey,
invoicerCorpNum = PopbillConfig.CorpNum, invoicerCorpNum = PopbillConfig.CorpNum,
invoicerBizClass = corpInfo?.bizClass, invoicerBizClass = corpInfo?.bizClass,
invoicerBizType = corpInfo?.bizType, invoicerBizType = corpInfo?.bizType,
@ -131,154 +156,232 @@ namespace NP.Base.Popbill
invoicerTEL = contact?.tel invoicerTEL = contact?.tel
}; };
} }
result.Data = MakeTaxinvoice(result.Data, payTax, payItems);
}
catch (PopbillException ex) catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message; result.Message = ex.Message;
Logger.TryError(ex.Message, ex); Logger.TryError(ex.Message, ex);
} }
return result; return result;
} }
#endregion
#region ()
/// <summary> /// <summary>
/// 세금계산서 임시저장 /// 세금계산서 임시저장(수정)
/// </summary> /// </summary>
/// <param name="taxinvoice">Taxinvoice</param> /// <param name="payTax">payTax</param>
/// <returns>IssueResponse</returns> /// <param name="payItems">payItems</param>
public static Result<Response> Register(Taxinvoice taxinvoice) /// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>mgtkey</returns>
/// <remarks>작성된 세금계산서 데이터를 팝빌에 저장합니다.</remarks>
public static Result<string> TempSave(PayTax payTax, IList<PayItem> payItems, MgtKeyType keyType = MgtKeyType.SELL)
{ {
Result<Response> result = new Result<Response>(); Result<string> result = new Result<string>();
try try
{ {
result.Data = PopbillConfig.taxinvoiceService.Register(PopbillConfig.CorpNum, taxinvoice); 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) catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message; result.Message = ex.Message;
Logger.TryError(ex.Message, ex); Logger.TryError(ex.Message, ex);
} }
return result; return result;
} }
#endregion
#region
/// <summary> /// <summary>
/// 세금계산서 발행 /// 세금계산서 발행
/// </summary> /// </summary>
/// <param name="mgtkey">파트너가 할당한 문서번호</param> /// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param> /// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <param name="forceIssue">지연발행 가능여부</param>
/// <param name="memo">메모</param> /// <param name="memo">메모</param>
/// <returns>IssueResponse</returns> /// <returns>IssueResponse</returns>
public static Result<IssueResponse> Issue(string mgtkey, MgtKeyType mgtKeyType = MgtKeyType.SELL, string memo = "") /// <remarks>"임시저장" 또는 "(역)발행대기" 상태의 세금계산서를 발행(전자서명)하며, "발행완료" 상태로 처리합니다</remarks>
public static Result<IssueResponse> Issue(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL, bool forceIssue = false, string memo = "")
{ {
Result<IssueResponse> result = new Result<IssueResponse>(); Result<IssueResponse> result = new Result<IssueResponse>();
try try
{ {
result.Data = PopbillConfig.taxinvoiceService.Issue(PopbillConfig.CorpNum, mgtKeyType, mgtkey, memo, PopbillConfig.UserID); 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) catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message; result.Message = ex.Message;
Logger.TryError(ex.Message, ex); Logger.TryError(ex.Message, ex);
} }
return result; return result;
} }
#endregion
#region
/// <summary> /// <summary>
/// 세금계산서 발행취소 /// 세금계산서 발행취소
/// </summary> /// </summary>
/// <param name="mgtkey">파트너가 할당한 문서번호</param> /// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <param name="memo">메모</param> /// <param name="memo">메모</param>
/// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>IssueResponse</returns> /// <returns>IssueResponse</returns>
public static Result<Response> CancelIssue(string mgtkey, MgtKeyType mgtKeyType = MgtKeyType.SELL, string memo = "") /// <remarks>국세청 전송 이전 "발행완료" 상태의 전자세금계산서를 "발행취소"하고, 해당 건은 국세청 신고 대상에서 제외됩니다.</remarks>
public static Result<Response> CancelIssue(string mgtkey, string memo = "", MgtKeyType keyType = MgtKeyType.SELL)
{ {
Result<Response> result = new Result<Response>(); Result<Response> result = new Result<Response>();
try try
{ {
result.Data = PopbillConfig.taxinvoiceService.CancelIssue(PopbillConfig.CorpNum, mgtKeyType, mgtkey, memo, PopbillConfig.UserID); 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) catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message; result.Message = ex.Message;
Logger.TryError(ex.Message, ex); Logger.TryError(ex.Message, ex);
} }
return result; return result;
} }
#endregion
#region
/// <summary>
/// 세금계산서 삭제 (국세청으로 전송되지 않은 세금계산서를 삭제합니다.)
/// </summary>
/// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>IssueResponse</returns>
/// <remarks>국세청으로 전송되지 않은 세금계산서를 삭제합니다.</remarks>
public static Result<Response> Delete(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL)
{
Result<Response> result = new Result<Response>();
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
/// <summary> /// <summary>
/// 세금계산서 즉시 발행 /// 세금계산서 즉시 발행
/// </summary> /// </summary>
/// <param name="taxinvoice">Taxinvoice</param> /// <param name="payTax">payTax</param>
/// <param name="payItems">payItems</param>
/// <param name="forceIssue">지연발행 가능여부</param> /// <param name="forceIssue">지연발행 가능여부</param>
/// <param name="memo">메모</param> /// <param name="memo">메모</param>
/// <returns>IssueResponse</returns> /// <returns>IssueResponse</returns>
public static Result<IssueResponse> RegistIssue(Taxinvoice taxinvoice, bool forceIssue = false, string memo = "") /// <remarks>작성된 세금계산서 데이터를 팝빌에 저장과 동시에 발행(전자서명)하여 "발행완료" 상태로 처리합니다.</remarks>
public static Result<IssueResponse> RegistIssue(PayTax payTax, IList<PayItem> payItems, bool forceIssue = false, string memo = "")
{ {
Result<IssueResponse> result = new Result<IssueResponse>(); ; Result<IssueResponse> result = new Result<IssueResponse>(); ;
try try
{ {
var taxinvoice = GetTaxinvoice(payTax, payItems).Data;
result.Data = PopbillConfig.taxinvoiceService.RegistIssue(PopbillConfig.CorpNum, taxinvoice, forceIssue, memo); result.Data = PopbillConfig.taxinvoiceService.RegistIssue(PopbillConfig.CorpNum, taxinvoice, forceIssue, memo);
result.Code = result.Data.code;
result.Message = result.Data.message;
} }
catch (PopbillException ex) catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message; result.Message = ex.Message;
Logger.TryError(ex.Message, ex); Logger.TryError(ex.Message, ex);
} }
return result; return result;
} }
#endregion
#region URL
/// <summary> /// <summary>
/// 세금계산서 인쇄 팝업 URL 확인 /// 세금계산서 인쇄 팝업 URL 확인
/// </summary> /// </summary>
/// <param name="mgtkey">파트너가 할당한 문서번호</param> /// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param> /// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>URL</returns> /// <returns>URL</returns>
public static Result<string> GetPrintURL(string mgtkey, MgtKeyType mgtKeyType = MgtKeyType.SELL) public static Result<string> GetPrintURL(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL)
{ {
Result<string> result = new Result<string>(); ; Result<string> result = new Result<string>(); ;
try try
{ {
result.Data = PopbillConfig.taxinvoiceService.GetPrintURL(PopbillConfig.CorpNum, mgtKeyType, mgtkey, PopbillConfig.UserID); result.Data = PopbillConfig.taxinvoiceService.GetPrintURL(PopbillConfig.CorpNum, keyType, mgtkey, PopbillConfig.UserID);
} }
catch (PopbillException ex) catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message; result.Message = ex.Message;
Logger.TryError(ex.Message, ex); Logger.TryError(ex.Message, ex);
} }
return result; return result;
} }
#endregion
#region URL -
/// <summary> /// <summary>
/// 세금계산서 인쇄 팝업 URL 확인 - 공급받는자용 /// 세금계산서 인쇄 팝업 URL 확인 - 공급받는자용
/// </summary> /// </summary>
/// <param name="mgtkey">파트너가 할당한 문서번호</param> /// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param> /// <param name="keyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>URL</returns> /// <returns>URL</returns>
public static Result<string> GetEPrintURL(string mgtkey, MgtKeyType mgtKeyType = MgtKeyType.SELL) public static Result<string> GetEPrintURL(string mgtkey, MgtKeyType keyType = MgtKeyType.SELL)
{ {
Result<string> result = new Result<string>(); ; Result<string> result = new Result<string>(); ;
try try
{ {
result.Data = PopbillConfig.taxinvoiceService.GetEPrintURL(PopbillConfig.CorpNum, mgtKeyType, mgtkey, PopbillConfig.UserID); result.Data = PopbillConfig.taxinvoiceService.GetEPrintURL(PopbillConfig.CorpNum, keyType, mgtkey, PopbillConfig.UserID);
} }
catch (PopbillException ex) catch (PopbillException ex)
{ {
result.Code = ex.code.ToString(); result.IsSuccess = false;
result.Code = ex.code;
result.Message = ex.Message; result.Message = ex.Message;
Logger.TryError(ex.Message, ex); Logger.TryError(ex.Message, ex);
} }
return result; return result;
} }
#endregion
} }
public class Result<T> public class Result<T>
{ {
public String Code = null; public bool IsSuccess = true;
public String Message = null; public long Code = 1;
public String Message = string.Empty;
public T Data; public T Data;
} }
} }

View File

@ -1311,9 +1311,9 @@
where a.payno=#payno# where a.payno=#payno#
</select> </select>
<select id="cr.paytax.formgtkey" parameterClass="hashtable" resultClass="paytax"> <select id="cr.paytax.formgtkey" parameterClass="hashtable" resultClass="paytax">
select taxno, taxdate, mgtkey select taxno, mgtkey
from paytax from paytax
where taxdate=#taxdate# where mgtkey like concat(#taxdate#,'%')
order by mgtkey desc order by mgtkey desc
limit 1 limit 1
</select> </select>