diff --git a/RMuseum/Controllers/DonationAccountingController.cs b/RMuseum/Controllers/DonationAccountingController.cs index 09e07f8b..1e3f78be 100644 --- a/RMuseum/Controllers/DonationAccountingController.cs +++ b/RMuseum/Controllers/DonationAccountingController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using RMuseum.Models.Accounting; using RMuseum.Models.Accounting.ViewModels; using RMuseum.Models.Auth.Memory; using RMuseum.Services; @@ -41,6 +42,34 @@ namespace RMuseum.Controllers } } + /// + /// add expense + regenerate donations page + /// + /// + /// + + [HttpPost("expense")] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.Donations)] + [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorDonationViewModel))] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + [ProducesResponseType((int)HttpStatusCode.Unauthorized)] + public async Task AddExpense([FromBody] GanjoorExpense expense) + { + try + { + Guid userId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value); + + var res = await _donationService.AddExpense(userId, expense); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + return Ok(res.Result); + } + catch (Exception exp) + { + return BadRequest(exp.ToString()); + } + } + /// /// one time import /// diff --git a/RMuseum/RMuseum.xml b/RMuseum/RMuseum.xml index 9fc24724..b31b6302 100644 --- a/RMuseum/RMuseum.xml +++ b/RMuseum/RMuseum.xml @@ -591,6 +591,13 @@ + + + add expense + regenerate donations page + + + + one time import @@ -6831,6 +6838,14 @@ + + + new expense + + + + + parse html of https://ganjoor.net/donate/ and fill the records @@ -7914,6 +7929,14 @@ + + + new expense + + + + + donation page row diff --git a/RMuseum/Services/IDonationService.cs b/RMuseum/Services/IDonationService.cs index c2e87d9e..30dac966 100644 --- a/RMuseum/Services/IDonationService.cs +++ b/RMuseum/Services/IDonationService.cs @@ -1,4 +1,5 @@ -using RMuseum.Models.Accounting.ViewModels; +using RMuseum.Models.Accounting; +using RMuseum.Models.Accounting.ViewModels; using RSecurityBackend.Models.Generic; using System; using System.Threading.Tasks; @@ -18,6 +19,14 @@ namespace RMuseum.Services /// Task> AddDonation(Guid editingUserId, GanjoorDonationViewModel donation); + /// + /// new expense + /// + /// + /// + /// + Task> AddExpense(Guid editingUserId, GanjoorExpense expense); + /// /// parse html of https://ganjoor.net/donate/ and fill the records /// diff --git a/RMuseum/Services/Implementation/DonationService.cs b/RMuseum/Services/Implementation/DonationService.cs index a78f2dfb..14326bb1 100644 --- a/RMuseum/Services/Implementation/DonationService.cs +++ b/RMuseum/Services/Implementation/DonationService.cs @@ -51,7 +51,7 @@ namespace RMuseum.Services.Implementation _context.GanjoorDonations.Add(d); await _context.SaveChangesAsync(); - if(!string.IsNullOrEmpty(d.Unit)) + if(!string.IsNullOrEmpty(d.Unit) && d.Amount > 0) { var expenses = await _context.GanjoorExpenses @@ -78,10 +78,13 @@ namespace RMuseum.Services.Implementation expense.DonationExpenditures.Add(n); _context.GanjoorExpenses.Update(expense); - var part = expense.DonationExpenditures.Count == 0 && remaining == d.Amount ? "" : "بخشی از "; + var amount = d.Remaining == d.Amount && remaining == d.Remaining ? "" : d.Remaining == remaining ? "" : $"مبلغ {remaining.ToString("N0", new CultureInfo("fa-IR")).ToPersianNumbers()} {d.Unit} آن "; + var part = expense.DonationExpenditures.Count == 0 && remaining == expense.Amount ? "" : "بخشی از "; if (!string.IsNullOrEmpty(d.ExpenditureDesc)) d.ExpenditureDesc += " "; - d.ExpenditureDesc += $"جهت تأمین {part}هزینهٔ {expense.Description} به مبلغ {expense.Amount.ToString("N0", new CultureInfo("fa-IR")).ToPersianNumbers()} {d.Unit} صرف شد."; + DateTime expenseDate = expense.ExpenseDate; + var dateString = $"{expenseDate.ToPersianYearMonthDay().Day.ToPersianNumbers()}م {PersianCulture.GetPersianMonthName(expenseDate.ToPersianYearMonthDay().Month)} {expenseDate.ToPersianYearMonthDay().Year.ToPersianNumbers()}"; + d.ExpenditureDesc += $"{amount}جهت تأمین {part}هزینهٔ {expense.Description} به مبلغ {expense.Amount.ToString("N0", new CultureInfo("fa-IR")).ToPersianNumbers()} {d.Unit} صرف شد ({dateString})."; d.Remaining -= remaining; _context.GanjoorDonations.Update(d); await _context.SaveChangesAsync(); @@ -108,6 +111,73 @@ namespace RMuseum.Services.Implementation } } + + /// + /// new expense + /// + /// + /// + /// + public async Task> AddExpense(Guid editingUserId, GanjoorExpense expense) + { + try + { + expense.DonationExpenditures = new List();//fix swagger posting a list which causes a donation to be added + _context.GanjoorExpenses.Add(expense); + await _context.SaveChangesAsync(); + + if(!string.IsNullOrEmpty(expense.Unit) && expense.Amount > 0) + { + var expenseRemaining = expense.Amount; + + var donations = await _context.GanjoorDonations.Where(d => d.Unit == expense.Unit && d.Remaining > 0).OrderBy(d => d.Id).ToListAsync(); + foreach(var d in donations) + { + if (expenseRemaining <= 0) + break; + + var remaining = expenseRemaining; + if (remaining > d.Remaining) + { + remaining = d.Remaining; + } + + DonationExpenditure n = new DonationExpenditure() + { + Amount = remaining, + GanjoorDonationId = d.Id + }; + + expense.DonationExpenditures.Add(n); + _context.GanjoorExpenses.Update(expense); + + var amount = d.Remaining == d.Amount && remaining == d.Remaining ? "" : d.Remaining == remaining ? "باقیماندهٔ آن " : $"مبلغ {remaining.ToString("N0", new CultureInfo("fa-IR")).ToPersianNumbers()} {d.Unit} آن "; + var part = expense.DonationExpenditures.Count == 1 && remaining == expenseRemaining ? "" : "بخشی از "; + if (!string.IsNullOrEmpty(d.ExpenditureDesc)) + d.ExpenditureDesc += " "; + DateTime expenseDate = expense.ExpenseDate; + var dateString = $"{expenseDate.ToPersianYearMonthDay().Day.ToPersianNumbers()}م {PersianCulture.GetPersianMonthName(expenseDate.ToPersianYearMonthDay().Month)} {expenseDate.ToPersianYearMonthDay().Year.ToPersianNumbers()}"; + d.ExpenditureDesc += $"{amount}جهت تأمین {part}هزینهٔ {expense.Description} به مبلغ {expense.Amount.ToString("N0", new CultureInfo("fa-IR")).ToPersianNumbers()} {d.Unit} صرف شد ({dateString})."; + d.Remaining -= remaining; + _context.GanjoorDonations.Update(d); + + + await _context.SaveChangesAsync(); + + expenseRemaining -= remaining; + } + } + + await RegenerateDonationsPage(editingUserId);//ignore possible errors here! + + return new RServiceResult(expense); + } + catch(Exception exp) + { + return new RServiceResult(null, exp.ToString()); + } + } + /// /// donation page row /// @@ -311,6 +381,18 @@ namespace RMuseum.Services.Implementation string htmlText = ""; + DateTime dateLastDonation = donations.Length > 0 ? donations[0].RecordDate : DateTime.MinValue; + DateTime dateLastExpense = DateTime.MinValue; + var lastExpense = await _context.GanjoorExpenses.OrderByDescending(e => e.ExpenseDate).FirstOrDefaultAsync(); + if(lastExpense != null) + { + dateLastExpense = lastExpense.ExpenseDate; + } + + DateTime last = dateLastDonation > dateLastExpense ? dateLastDonation : dateLastExpense; + + var dateString = $"{last.ToPersianYearMonthDay().Day.ToPersianNumbers()}م {PersianCulture.GetPersianMonthName(last.ToPersianYearMonthDay().Month)} {last.ToPersianYearMonthDay().Year.ToPersianNumbers()}"; + htmlText += $"

{Environment.NewLine}"; htmlText += $"در صورت تمایل به کمک مالی به گنجور از طریق کارت عابربانک؛ لطفاً کمکهای خود را به کارت شمارهٔ 6219-8610-2780-4979 (بانک سامان) به نام حمیدرضا محمدی واریز نمایید. علاوه بر آن از طریق اینترنت‌بانک سامان می‌توانید کمکهای خود را به شماره حساب ۸۲۸-۸۰۰-۸۷۳۳۳۰-۱ (شمارهٔ شبا: IR03-0560-0828-8000-0873-3300-01) واریز نمایید. لطفاً از طریق تماس با نشانی ganjoor@ganjoor.net مشخصات خودتان و مبلغ واریزی را اطلاع دهید (نام کمک دهندگان و نوع استفاده‌ای که از کمک آنها شده به مرور در همین صفحه به اطلاع خواهد رسید).{Environment.NewLine}"; htmlText += $"

{Environment.NewLine}";