팝빌 세금계산서 관련 작업 중간 커밋

This commit is contained in:
lch 2021-04-23 09:18:52 +00:00
parent 4b516f4c33
commit c7e8b41869
8 changed files with 265 additions and 63 deletions

View File

@ -62,6 +62,9 @@
<Reference Include="IBatisNet.Common.Logging.Log4Net">
<HintPath>..\..\LMS_TSTI\Source\Core\NPTech.LMS.Core\bin\Release\IBatisNet.Common.Logging.Log4Net.dll</HintPath>
</Reference>
<Reference Include="Linkhub">
<HintPath>..\References\Popbill\Linkhub.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\References\log4net.dll</HintPath>
@ -77,6 +80,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\References\NPDao.dll</HintPath>
</Reference>
<Reference Include="Popbill">
<HintPath>..\References\Popbill\Popbill.dll</HintPath>
</Reference>
<Reference Include="Spring.Aop, Version=2.0.1.45000, Culture=neutral, PublicKeyToken=65e474d141e25e07, processorArchitecture=MSIL">
<HintPath>..\packages\Spring.Aop.2.0.1\lib\net45\Spring.Aop.dll</HintPath>
</Reference>

View File

@ -5,6 +5,8 @@ using System.Net.Http;
using System.Web.Mvc;
using NP.Model;
using NP.Base.Popbill;
using Popbill.Taxinvoice;
using System.Collections;
namespace NP.BO.Controllers
{
@ -793,14 +795,16 @@ namespace NP.BO.Controllers
vm.PayTaxItem = Dao.Get<PayItem>("cr.paytaxitem2", new System.Collections.Hashtable() { { "taxno", vm.longval } });
#region Popbill
var mgtKey = vm.PayTaxes.First()?.mgtKey;
if (!string.IsNullOrEmpty(mgtKey))
var mgtkey = vm.PayTaxes.First()?.mgtkey;
if (!string.IsNullOrEmpty(mgtkey))
{
ViewBag.Taxinvoice = PopbillService.GetTaxinvoice(mgtKey);
ViewBag.Taxinvoice = PopbillService.GetTaxinvoice(mgtkey).Data;
}
else
{
ViewBag.Taxinvoice = PopbillService.GetTaxinvoiceR();
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

View File

@ -5,7 +5,7 @@
<div>
<ul class="pagination pagination-md" style="margin: 0;">
<li class="active"><a href="#" data-toggle="tab">요청현황</a></li>
<li><a href="#" onclick="gotab();" data-toggle="tab">스마트빌</a></li>
@*<li><a href="#" onclick="gotab();" data-toggle="tab">스마트빌</a></li>*@
</ul>
</div>
<form id="mform" method="post">

View File

@ -1,6 +1,7 @@
@model NP.Model.VMCRoom
@{
var t = Model.PayTaxes.First();
var taxinvoice = ViewBag.Taxinvoice;
}
<div>
<ul class="pagination pagination-md" style="margin: 0;">
@ -27,17 +28,17 @@
<tbody class="data" id="tbody1">
@foreach (var d in Model.PayTaxes)
{
<tr>
<td>@d.payno</td>
<td class="left">@Html.Raw(string.Format("<span class=\"isjoin{0}\">{1}</span> {2}", d.isjoin, d.isjoin == 1 ? "정" : "비", d.asname))</td>
<td>@string.Format("{0}({1})", d.username, d.userid)</td>
<td class="left">@d.itemname @(d.ccount > 1 ? string.Format("외 {0}건", d.ccount - 1) : "")</td>
<td>@d.pcnt</td>
<td class="right">@d.taxamt.ToString("#,0")</td>
<td>@d.cdtymd</td>
<td>@(d.taxdate == null ? "" : d.taxdate.Value.ToString("yyyy-MM-dd"))</td>
<td class="taxdate@(d.iscancel ==1 ? "" : d.taxdate==null?"x":"")">@(d.iscancel ==1 ? "발행취소" :d.taxdate == null ? "미발행" : "발행완료")</td>
</tr>
<tr>
<td>@d.payno</td>
<td class="left">@Html.Raw(string.Format("<span class=\"isjoin{0}\">{1}</span> {2}", d.isjoin, d.isjoin == 1 ? "정" : "비", d.asname))</td>
<td>@string.Format("{0}({1})", d.username, d.userid)</td>
<td class="left">@d.itemname @(d.ccount > 1 ? string.Format("외 {0}건", d.ccount - 1) : "")</td>
<td>@d.pcnt</td>
<td class="right">@d.taxamt.ToString("#,0")</td>
<td>@d.cdtymd</td>
<td>@(d.taxdate == null ? "" : d.taxdate.Value.ToString("yyyy-MM-dd"))</td>
<td class="taxdate@(d.iscancel ==1 ? "" : d.taxdate==null?"x":"")">@(d.iscancel ==1 ? "발행취소" :d.taxdate == null ? "미발행" : "발행완료")</td>
</tr>
}
</tbody>
@ -97,7 +98,8 @@
<th>발행요청금액</th>
<td>@(t.taxamt.ToString("#,0"))원</td>
</tr>
</tbody></table>
</tbody>
</table>
</section>
<form id="sform" method="post">
<section class="panel panel-default">
@ -107,33 +109,33 @@
<tbody>
<tr>
<th>회사명</th>
<td><input type="text" class="form-control dev" name="asname" value="@ViewBag.Taxinvoice.invoicerCorpName" /></td>
<td><input type="text" class="form-control dev" name="invoicerCorpName" value="@taxinvoice.invoicerCorpName" /></td>
<th>대표자</th>
<td><input type="text" class="form-control dev" name="ceoname" value="@ViewBag.Taxinvoice.invoicerCEOName" /></td>
<td><input type="text" class="form-control dev" name="invoicerCEOName" value="@taxinvoice.invoicerCEOName" /></td>
</tr>
<tr>
<th>사업자등록번호</th>
<td><input type="text" class="form-control dev" name="brno" value="@ViewBag.Taxinvoice.invoicerCorpNum" /></td>
<td><input type="text" class="form-control dev" name="invoicerCorpNum" value="@taxinvoice.invoicerCorpNum" /></td>
<th>업태</th>
<td><input type="text" class="form-control dev" name="btype" value="@ViewBag.Taxinvoice.invoicerBizType" /></td>
<td><input type="text" class="form-control dev" name="invoicerBizType" value="@taxinvoice.invoicerBizType" /></td>
</tr>
<tr>
<th>종목</th>
<td><input type="text" class="form-control dev" name="bkind" value="@ViewBag.Taxinvoice.invoicerBizClass" /></td>
<td><input type="text" class="form-control dev" name="invoicerBizClass" value="@taxinvoice.invoicerBizClass" /></td>
<th>사업장주소</th>
<td><input type="text" class="form-control dev" name="asaddr" value="@ViewBag.Taxinvoice.invoicerAddr" /></td>
<td><input type="text" class="form-control dev" name="invoicerAddr" value="@taxinvoice.invoicerAddr" /></td>
</tr>
<tr>
<th>담당자</th>
<td><input type="text" class="form-control dev" name="manname" value="@ViewBag.Taxinvoice.invoicerContactName" /></td>
<td><input type="text" class="form-control dev" name="invoicerContactName" value="@taxinvoice.invoicerContactName" /></td>
<th>연락처</th>
<td><input type="text" class="form-control dev" name="telno" value="@ViewBag.Taxinvoice.invoicerTEL" /></td>
<td><input type="text" class="form-control dev" name="invoicerTEL" value="@taxinvoice.invoicerTEL" /></td>
</tr>
<tr>
<th>이메일주소</th>
<td><input type="text" class="form-control dev" name="email" value="@ViewBag.Taxinvoice.invoicerEmail" /></td>
<td><input type="text" class="form-control dev" name="invoicerEmail" value="@taxinvoice.invoicerEmail" /></td>
<th>문서번호</th>
<td><input type="text" class="form-control dev" name="email" value="@ViewBag.Taxinvoice.invoicerMgtKey" placeholder="결제일-결제번호?" /></td>
<td><input type="text" class="form-control dev" name="invoiceeMgtKey" value="@taxinvoice.invoicerMgtKey" /></td>
</tr>
</tbody>
</table>
@ -174,7 +176,7 @@
<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="hidden" class="form-control dev" name="iscancel" value="@t.iscancel" />
<label><input type="checkbox" id="iscanceled" /> 발행취소</label>
<label style="display:none;"><input type="checkbox" id="iscanceled" /> 발행취소</label>
</td>
</tr>
<tr>
@ -206,8 +208,27 @@
<input type="hidden" name="taxno" value="@t.taxno" />
<input type="hidden" name="payno" value="@t.payno" />
<input type="hidden" name="cno" value="@t.cno" />
<input type="hidden" name="mgtkey" value="@t.mgtkey" />
<div class="text-center">
<a href="#" class="btn btn-primary" onclick="save();">저장</a>
@if (string.IsNullOrEmpty(t.mgtkey))
{
<a href="#" class="btn btn-success" onclick="register();">임시저장 및 미리보기</a>
<a href="#" class="btn btn-success" onclick="registIssue();">계산서 즉시발행</a>
}
else
{
if (string.IsNullOrEmpty(taxinvoice.ntsconfirmNum))
{
<a href="#" class="btn btn-success" onclick="register();">임시저장 및 미리보기</a>
<a href="#" class="btn btn-success" onclick="registIssue();">계산서 즉시발행</a>
}
else
{
<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>
</div>
@Html.Partial("./Partial/dform", Model)
@ -275,5 +296,19 @@
msgadmin();
}
}
function register() {
}
function view() {
}
function registIssue() {
}
function cancelIssue() {
}
</script>
}

View File

@ -773,6 +773,66 @@ namespace NP.Base.Controllers
}
return JsonOK(Dao.Save("cr.paytax.save", d));
}
/// <summary>
/// 팝빌 임시저장 및 미리보기(팝빌 임시저장 및 paytax.mgtkey 업데이트 후 세금계산서 인쇄 url 리턴)
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
[HttpPost]
public JsonResult PayTaxRegister(PayTax d)
{
d.uno = SUserInfo.UserNo; d.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)
{
return JsonBack(new JsonRtn() { code = -1 });
}
return JsonOK(Dao.Save("cr.paytax.save", d));
}
/// <summary>
/// 계산서 즉시발행(팝빌 발행 및 paytax.taxdate ,paytax.mgtkey 업데이트)
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
[HttpPost]
public JsonResult PayTaxRegistIssue(PayTax d)
{
d.uno = SUserInfo.UserNo; d.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)
{
return JsonBack(new JsonRtn() { code = -1 });
}
return JsonOK(Dao.Save("cr.paytax.save", d));
}
/// <summary>
/// 발행취소(발행전: paytax.iscancel 상태값 변경, 발행완료: 팝빌 발행취소 및 paytax.iscancel 상태값 변경)
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
[HttpPost]
public JsonResult PayTaxCancelIssue(PayTax d)
{
d.uno = SUserInfo.UserNo; d.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)
{
return JsonBack(new JsonRtn() { code = -1 });
}
return JsonOK(Dao.Save("cr.paytax.save", d));
}
/// <summary>
/// 계산서조회(팝빌 세금계산서 인쇄 url 리턴)
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
[HttpPost]
public JsonResult PayTaxView(PayTax d)
{
d.uno = SUserInfo.UserNo; d.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)
{
return JsonBack(new JsonRtn() { code = -1 });
}
return JsonOK(Dao.Save("cr.paytax.save", d));
}
[HttpPost]
public JsonResult SmartTaxView(String csid)
{

View File

@ -1,7 +1,10 @@
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;
@ -13,59 +16,112 @@ namespace NP.Base.Popbill
/// <summary>
/// 세금계산서 문서번호{mgtKey} 생성
/// </summary>
/// <returns></returns>
public static string MakeMgtKey()
/// <param name="Dao">CommonDao</param>
/// <param name="taxdate">발행일</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>mgtKey</returns>
public static Result<String> MakeMgtKey(CommonDao Dao, DateTime taxdate, MgtKeyType mgtKeyType = MgtKeyType.SELL)
{
string mgtKey = string.Empty;
Result<String> result = new Result<string>();
try
{
string date = DateTime.Now.ToString("yyyy-MM-dd");
string no = 1.ToString("D5");//수정->발행문서 검색 후 순번 + 1 하는 거로 변경
mgtKey = $"{date}-L{no}";
string mgtkey = string.Empty;
int no = 1;
var payTax = Dao.Get<PayTax>("cr.paytax.formgtkey", new Hashtable() { { "taxdate", taxdate } }).FirstOrDefault();
if (payTax == null)
{
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);
if (int.TryParse(strNo, out no))
{
++no;
}
}
mgtkey = $"{taxdate:yyyy-MM-dd}-L{no:D5}";
bool isUse = true;
int checkLimit = 10;
while (isUse && checkLimit > 0)
{
isUse = PopbillConfig.taxinvoiceService.CheckMgtKeyInUse(PopbillConfig.CorpNum, mgtKeyType, mgtkey);
if (isUse)
{
++no;
mgtkey = $"{taxdate:yyyy-MM-dd}-L{no:D5}";
}
--checkLimit;
}
result.Data = mgtkey;
}
catch (PopbillException ex)
{
result.Code = ex.code.ToString();
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return mgtKey;
return result;
}
/// <summary>
/// 세금계산서 상세정보
/// </summary>
/// <param name="mgtKey"></param>
/// <returns></returns>
public static Taxinvoice GetTaxinvoice(string mgtKey)
/// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <param name="mgtKeyType">세금계산서 유형 : SELL = 매출, BUY = 매입, TRUSTEE = 위수탁</param>
/// <returns>Taxinvoice</returns>
public static Result<Taxinvoice> GetTaxinvoice(string mgtkey, MgtKeyType mgtKeyType = MgtKeyType.SELL)
{
Taxinvoice taxinvoice = null;
Result<Taxinvoice> result = new Result<Taxinvoice>();
try
{
taxinvoice = PopbillConfig.taxinvoiceService.GetDetailInfo(PopbillConfig.CorpNum, MgtKeyType.SELL, mgtKey);
result.Data = PopbillConfig.taxinvoiceService.GetDetailInfo(PopbillConfig.CorpNum, mgtKeyType, mgtkey);
}
catch (PopbillException ex)
{
result.Code = ex.code.ToString();
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return taxinvoice;
finally
{
if (result.Data == null)
{
result.Data = new Taxinvoice() { invoicerMgtKey = mgtkey };
}
}
return result;
}
/// <summary>
/// 세금계산서 공급자정보
/// </summary>
/// <returns></returns>
public static Taxinvoice GetTaxinvoiceR()
/// <param name="mgtkey">파트너가 할당한 문서번호</param>
/// <returns>Taxinvoice</returns>
public static Result<Taxinvoice> GetTaxinvoiceR(string mgtkey)
{
Taxinvoice Taxinvoice = null;
Result<Taxinvoice> result = new Result<Taxinvoice>();
try
{
CorpInfo corpInfo = PopbillConfig.taxinvoiceService.GetCorpInfo(PopbillConfig.CorpNum, PopbillConfig.UserID);
Contact contact = PopbillConfig.taxinvoiceService.ListContact(PopbillConfig.CorpNum, PopbillConfig.UserID).Where(w => w.mgrYN == true).FirstOrDefault();
Taxinvoice = new Taxinvoice
result.Data = new Taxinvoice
{
invoicerAddr = corpInfo?.addr,
invoicerCEOName = corpInfo?.ceoname,
invoicerCorpName = corpInfo?.corpName,
invoicerMgtKey = MakeMgtKey(),
invoicerMgtKey = mgtkey,
invoicerCorpNum = PopbillConfig.CorpNum,
invoicerBizClass = corpInfo?.bizClass,
invoicerBizType = corpInfo?.bizType,
@ -77,30 +133,62 @@ namespace NP.Base.Popbill
}
catch (PopbillException ex)
{
result.Code = ex.code.ToString();
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return Taxinvoice;
return result;
}
/// <summary>
/// 세금계산서 임시저장
/// </summary>
/// <param name="taxinvoice">Taxinvoice</param>
/// <returns>IssueResponse</returns>
public static Result<Response> Register(Taxinvoice taxinvoice)
{
Result<Response> result = new Result<Response>();
try
{
result.Data = PopbillConfig.taxinvoiceService.Register(PopbillConfig.CorpNum, taxinvoice);
}
catch (PopbillException ex)
{
result.Code = ex.code.ToString();
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return result;
}
/// <summary>
/// 세금계산서 즉시 발행
/// </summary>
/// <param name="taxinvoice"></param>
/// <param name="forceIssue"></param>
/// <param name="memo"></param>
/// <returns></returns>
public static IssueResponse RegistIssue(Taxinvoice taxinvoice, bool forceIssue, string memo)
/// <param name="taxinvoice">Taxinvoice</param>
/// <param name="forceIssue">지연발행 가능여부</param>
/// <param name="memo">메모</param>
/// <returns>IssueResponse</returns>
public static Result<IssueResponse> RegistIssue(Taxinvoice taxinvoice, bool forceIssue = false, string memo = "")
{
IssueResponse IssueResponse = null;
Result<IssueResponse> result = new Result<IssueResponse>();;
try
{
PopbillConfig.taxinvoiceService.RegistIssue(PopbillConfig.CorpNum, taxinvoice, forceIssue, memo);
result.Data = PopbillConfig.taxinvoiceService.RegistIssue(PopbillConfig.CorpNum, taxinvoice, forceIssue, memo);
}
catch (PopbillException ex)
{
result.Code = ex.code.ToString();
result.Message = ex.Message;
Logger.TryError(ex.Message, ex);
}
return IssueResponse;
return result;
}
}
public class Result<T>
{
public String Code = null;
public String Message = null;
public T Data;
}
}

View File

@ -1237,8 +1237,9 @@
,ua.isjoin
,row_number() over(order by b.cdt desc) rno
,count(a.taxno) over() pagetotalcount
,a.mgtkey
from (
select a.taxno,max(cm.cname) cname,a.asaddr,max(bk.bkname) bkname,max(ex.exname) exname,sum(pi.pcnt) pcnt,count(pi.pino) ccount
select a.taxno,max(cm.cname) cname,a.asaddr,max(bk.bkname) bkname,max(ex.exname) exname,sum(pi.pcnt) pcnt,count(pi.pino) ccount, a.mgtkey
from paytax a
inner join paytaxitem b on b.taxno=a.taxno
inner join payitem pi on pi.pino=b.pino
@ -1309,6 +1310,13 @@
from paytax a
where a.payno=#payno#
</select>
<select id="cr.paytax.formgtkey" parameterClass="hashtable" resultClass="paytax">
select taxno, taxdate, mgtkey
from paytax
where taxdate=#taxdate#
order by mgtkey desc
limit 1
</select>
<update id="cr.paytax.save" parameterClass="paytax">
update paytax
set <include refid="sql.up"></include>
@ -1324,6 +1332,7 @@
,taxdate=#taxdate#
,taxinfo=#taxinfo#
,iscancel=#iscancel#
,mgtkey=#mgtkey#
where taxno=#taxno#
</update>
<select id="cr.documnetspast" parameterClass="hashtable" resultClass="document">

View File

@ -916,9 +916,9 @@ namespace NP.Model
public String userid { get; set; }
public int? iscancel { get; set; }
/// <summary>
/// 세금계산서 문서번호
/// 세금계산서 문서번호 예)2020-01-01-L00001 {년도-월(2자리)-일(2자리)-L발행순서 일련번호(5자리)}
/// </summary>
public String mgtKey { get; set; }
public String mgtkey { get; set; }
}
[Serializable]
public class PayRfd : BaseModel