| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- @page
- @using Domain.Entities.Developers.ValueObject
- @model Admin.Pages.Developers.Purchases.IndexModel
- @{
- ViewData["Title"] = "결제 보고 내역";
- static string MarketLabel(ApiPurchaseMarketplace m) => m switch
- {
- ApiPurchaseMarketplace.GooglePlay => "구글",
- ApiPurchaseMarketplace.AppStore => "애플",
- ApiPurchaseMarketplace.Microsoft => "MS",
- ApiPurchaseMarketplace.GalaxyStore => "갤럭시",
- ApiPurchaseMarketplace.OneStore => "원스토어",
- _ => "기타"
- };
- }
- <div class="container-fluid">
- <h3>@ViewData["Title"]</h3>
- <hr />
- <partial name="_StatusMessage" />
- <form id="fAdminSearch" method="get">
- <div class="row g-2 align-items-end">
- <div class="col-6 col-sm-auto">
- <select name="status" id="status" class="form-select">
- <option value="">상태 전체</option>
- <option value="@((int)ApiPurchaseStatus.Pending)" selected="@(Model.Query.Status == ApiPurchaseStatus.Pending)">보류</option>
- <option value="@((int)ApiPurchaseStatus.Confirmed)" selected="@(Model.Query.Status == ApiPurchaseStatus.Confirmed)">확정</option>
- <option value="@((int)ApiPurchaseStatus.Canceled)" selected="@(Model.Query.Status == ApiPurchaseStatus.Canceled)">취소</option>
- </select>
- </div>
- <div class="col-6 col-sm-auto">
- <input type="date" name="from" class="form-control" value="@(Model.Query.From?.ToString("yyyy-MM-dd"))" />
- </div>
- <div class="col-6 col-sm-auto">
- <input type="date" name="to" class="form-control" value="@(Model.Query.To?.ToString("yyyy-MM-dd"))" />
- </div>
- <div class="col-12 col-sm col-md col-lg-auto">
- <input type="text" name="keyword" class="form-control" maxlength="255" value="@Model.Query.Keyword" placeholder="orderID/후원코드/게임코드/채널명" />
- </div>
- <div class="col-auto">
- <div class="form-check">
- <input type="checkbox" name="onlyMismatch" id="onlyMismatch" value="true" class="form-check-input" checked="@Model.Query.OnlyMismatch" />
- <label for="onlyMismatch" class="form-check-label">금액 불일치만</label>
- </div>
- </div>
- <div class="col-12 col-lg-auto">
- <button type="submit" class="btn btn-primary">검색</button>
- </div>
- </div>
- </form>
- <hr />
- @if (Model.Summary != null)
- {
- <div class="row g-2 mb-3">
- <div class="col-auto"><span class="badge bg-light text-dark border">보고액 합계 @Model.Summary.TotalOrderPrice.ToString("N0")원</span></div>
- <div class="col-auto"><span class="badge bg-light text-dark border">수수료 합계 @Model.Summary.TotalCommission.ToString("N0")원</span></div>
- <div class="col-auto"><span class="badge bg-secondary">보류 @Model.Summary.PendingCount.ToString("N0")</span></div>
- <div class="col-auto"><span class="badge bg-success">확정 @Model.Summary.ConfirmedCount.ToString("N0")</span></div>
- <div class="col-auto"><span class="badge bg-dark">취소 @Model.Summary.CanceledCount.ToString("N0")</span></div>
- @if (Model.Summary.MismatchCount > 0)
- {
- <div class="col-auto"><span class="badge bg-danger">금액 불일치 @Model.Summary.MismatchCount.ToString("N0")</span></div>
- }
- @if (Model.Summary.TotalShortfall > 0)
- {
- <div class="col-auto"><span class="badge bg-warning text-dark">미회수 @Model.Summary.TotalShortfall.ToString("N0")원</span></div>
- }
- </div>
- }
- <div class="row g-2 align-items-end mb-2">
- <div class="col">Total: @Model.Total.ToString("N0")</div>
- </div>
- <div class="table-responsive">
- <table class="table table-bordered table-hover">
- <thead>
- <tr>
- <th>ID</th>
- <th>등록일</th>
- <th>앱</th>
- <th>게임</th>
- <th>채널 (후원코드)</th>
- <th>마켓</th>
- <th>orderID</th>
- <th>SKU</th>
- <th class="text-end">보고액</th>
- <th class="text-end">수수료 (율)</th>
- <th>상태</th>
- <th>확정 예정/일시</th>
- </tr>
- </thead>
- <tbody>
- @if (Model.List.Count <= 0)
- {
- <tr>
- <td colspan="12" class="text-center text-muted py-4">No Data.</td>
- </tr>
- }
- else
- {
- @foreach (var row in Model.List)
- {
- <tr>
- <td>@row.ID</td>
- <td>@row.CreatedAt.ToString("yyyy-MM-dd HH:mm")</td>
- <td>@row.AppName</td>
- <td>@row.GameName</td>
- <td>@row.ChannelName (@(row.ChannelCode ?? "-"))</td>
- <td>@MarketLabel(row.Marketplace)</td>
- <td><code>@row.OrderID</code></td>
- <td>
- @(row.ProductID ?? "-")
- @if (row.PriceMismatched)
- {
- <span class="badge bg-danger" title="카탈로그 정가 @(row.CatalogPrice?.ToString("N0") ?? "-")원과 불일치">불일치</span>
- }
- </td>
- <td class="text-end">@row.OrderPrice.ToString("N0")원</td>
- <td class="text-end">@row.CommissionAmount.ToString("N0")원 (@row.CommissionRate%)</td>
- <td>
- @switch (row.Status)
- {
- case ApiPurchaseStatus.Pending:
- <span class="badge bg-secondary">보류</span>
- break;
- case ApiPurchaseStatus.Confirmed:
- <span class="badge bg-success">확정</span>
- break;
- case ApiPurchaseStatus.Canceled:
- <span class="badge bg-dark">취소</span>
- if (row.CancelWasConfirmed == true)
- {
- <small class="text-muted d-block">회수 @(row.RecoveredAmount?.ToString("N0") ?? "0")원</small>
- }
- if (row.ShortfallAmount > 0)
- {
- <span class="badge bg-warning text-dark">미회수 @(row.ShortfallAmount?.ToString("N0"))원</span>
- }
- break;
- }
- </td>
- <td>
- @if (row.Status == ApiPurchaseStatus.Pending)
- {
- @row.ConfirmDueAt.ToString("yyyy-MM-dd")
- <small class="text-muted">예정</small>
- }
- else if (row.ConfirmedAt != null)
- {
- @row.ConfirmedAt.Value.ToString("yyyy-MM-dd HH:mm")
- }
- else if (row.CanceledAt != null)
- {
- <small class="text-muted">@row.CanceledAt.Value.ToString("yyyy-MM-dd HH:mm") 취소</small>
- }
- </td>
- </tr>
- }
- }
- </tbody>
- </table>
- </div>
- @if (Model.Pagination != null)
- {
- <partial name="_Pagination" model="Model.Pagination" />
- }
- </div>
|