An open API service indexing awesome lists of open source software.

https://github.com/bunu23/reimbursement-submission

A .NET Core Web API for university employees to submit reimbursement receipts.
https://github.com/bunu23/reimbursement-submission

angular csharp css dotnet html mysql separation-of-concerns

Last synced: 6 months ago
JSON representation

A .NET Core Web API for university employees to submit reimbursement receipts.

Awesome Lists containing this project

README

          

# Reimbursement Submission

This project is a full-stack **Reimbursement Submission System** which includes the basic functionality of submitting and viewing reimbursement receipts. It allows university employees to submit and view receipts for reimbursement, including uploading receipt files, all connected via a RESTful API backed by MySQL.

I built this application from scratch using **ASP.NET Core Web API**, **MySQL**, and **Angular**, following clean architecture practices like Repository and Service layers.

---

## Table of Contents

- [What It Does?](#what-it-does)
- [Tech Stack, Architecture, Best Practices](#architecture-and-stack)
- [Why this Stack?](#why-this-stack)
- [Project Structure](#project-structure)
- [Getting Started](#getting-started)
- [Time Tracking](#time-tracking)
- [Comments](#comments)
- [Screenshot](#screenshot)

[πŸ”Ό Back to Top](#reimbursement-submission)

---

# What It Does

- **Receipt Submission Form**
Employees can fill out a simple, user-friendly form to submit reimbursement receipts. The form captures:

- **Purchase Date** – the date the expense was incurred
- **Amount** – how much was spent
- **Description** – a brief reason or context for the purchase (for example., "Conference lunch", "Office supplies")
- **Receipt File Upload (Optional)** – users may upload a digital copy of their receipt (for example PDF, image, word file.).

- **Data Storage in MySQL**
Submitted data is sent to a `.NET Core Web API` using a `POST` request and stored in a MySQL database.
The data model includes fields for date, amount, description, and an optional file path. Files are stored in a local `Uploads/` folder and linked via their relative path.

- **Receipt Listing**
After submission, the receipt appears instantly in a list below the form. This list displays:

- Receipt ID
- Submission date
- Amount and description
- A β€œView” link if a receipt file is available

- **Clean, Responsive UI**
The UI is built with custom CSS for a clean and modern feel, with:

- Responsive layout, form alignments
- Table format for listing receipts clearly

- **Frontend–Backend Integration**
The Angular frontend communicates with the backend through RESTful APIs:
- `POST` to submit a new receipt
- `GET` to fetch and display all submitted receipts
These endpoints use proper CORS setup and return real-time results.

[πŸ”Ό Back to Top](#reimbursement-submission)

---

# Architecture and Stack

This project follows a modular, layered architecture to ensure clarity, testability, and scalability:

#### Backend (.NET Core)

- **Repository Pattern**: Data access is abstracted , so data logic stays isolated.
- **Service Layer**: Business logic to keep controllers clean and handle reusable logic.
- **EF Core + MySQL**: Used to integrate with MySQL easily.
- **CORS Enabled**: Allows Angular frontend to talk to the API.
- **Code is modular and extensible** β€” it would be easy to add user authentication, pagination, or edit/delete features later on.

#### Frontend (Angular Standalone)

- **Angular Standalone Components**: Built entirelyusing the latest Angular features.
- **FormsModule + ngModel**: For two-way binding and simple form validation.
- **HttpClientModule**: REST API integration for GET/POST requests.
- **File Uploads**: Handled using `FormData` and `multipart/form-data` on both ends.
- **Conditional UI Rendering**: Receipt links only show if file is present.

[πŸ”Ό Back to Top](#reimbursement-submission)

---

## Why this Stack?

I typically work with **Java, React, and both relational and NoSQL databases**, but I saw this assessment as a great chance to step out of my usual tech stack and get hands-on with **.NET Core and Angular**. I have been meaning to explore them more seriously, and this project gave me the perfect opportunity to do that.

- I chose **.NET Core** because it’s fast, scalable, and well-suited for building clean API services.
- **MySQL** is something I am already comfortable with, and it integrates smoothly.
- On the frontend, I went with **Angular's new standalone component approach**, which felt modern and lightweight.
- I also kept the UI clean and responsive using just **HTML and CSS** β€” no heavy UI libraries β€” so everything stays fast and easy to maintain.

Overall, it was a fun challenge and a great learning experience to build a full-stack app independently using this stack!

[πŸ”Ό Back to Top](#reimbursement-submission)

---

# Project Structure

### Backend: `REIMBURSEMENT-API`

```
REIMBURSEMENT-API/
β”œβ”€β”€ .vscode/
β”œβ”€β”€ bin/
β”œβ”€β”€ obj/
β”œβ”€β”€ Controllers/
β”‚ └── ReceiptController.cs # API endpoints
β”œβ”€β”€ Data/
β”‚ └── AppDbContext.cs # Entity Framework Core DbContext
β”œβ”€β”€ Dto/
β”‚ └── ReceiptFormModel.cs # DTO for file + form data
β”œβ”€β”€ Models/
β”‚ └── Receipt.cs # Receipt entity model
β”œβ”€β”€ Repositories/
β”‚ β”œβ”€β”€ IReceiptRepository.cs # Interface for data access
β”‚ └── ReceiptRepository.cs # EF-based repository implementation
β”œβ”€β”€ Services/
β”‚ └── ReceiptService.cs # Business logic for receipt processing
β”œβ”€β”€ Uploads/
β”‚ └── # Uploaded receipt files are stored here
β”œβ”€β”€ appsettings.json # General app configuration
β”œβ”€β”€ appsettings.Development.json
β”œβ”€β”€ launchSettings.json
β”œβ”€β”€ Database-Script.txt # SQL script
β”œβ”€β”€ Program.cs # Application startup and configuration
β”œβ”€β”€ Reimbursement-Api.csproj
└── Reimbursement-Api.sln
```

### Frontend: `Reimbursement-Web`

```
REIMBURSEMENT-WEB/
β”œβ”€β”€ .angular/
β”œβ”€β”€ .vscode/
β”œβ”€β”€ coverage/
β”œβ”€β”€ node_modules/
β”œβ”€β”€ public/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ app/
β”‚ β”‚ β”œβ”€β”€ app.component.css # Component-specific styles
β”‚ β”‚ β”œβ”€β”€ app.component.html # Main UI template (form + table)
β”‚ β”‚ β”œβ”€β”€ app.component.spec.ts # Unit tests for AppComponent
β”‚ β”‚ β”œβ”€β”€ app.component.ts # Component logic & data handling
β”‚ β”‚ β”œβ”€β”€ app.config.ts
β”‚ β”‚ β”œβ”€β”€ app.routes.ts
β”‚
β”œβ”€β”€ package.json
β”œβ”€β”€ package-lock.json

```

[πŸ”Ό Back to Top](#reimbursement-submission)

---

# Getting Started

### βœ… Prerequisites

- [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0)
- [MySQL Server](https://dev.mysql.com/downloads/mysql/)
- [Node.js + npm](https://nodejs.org/)
- Angular CLI
```bash
npm install -g @angular/cli
```

---

### Backend Setup – `REIMBURSEMENT-API`

```bash
cd REIMBURSEMENT-API
```

1. Open `appsettings.json` and update your MySQL connection:

```json
"ConnectionStrings": {
"DefaultConnection": "server=localhost;port=3306;database=reimbursements;user=root;password=your_password"
}
```

> Replace `your_password` with your actual MySQL root password.

2. Run the following commands to update the database and start the API:

```bash
dotnet ef database update
dotnet run
```

## Frontend Setup – `Reimbursement-Web`

```bash
cd Reimbursement-Web
```

1. Install dependencies:

```bash
npm install
```

2. Start the Angular development server:

```bash
ng serve
```

App available at: [http://localhost:4200](http://localhost:4200)

[πŸ”Ό Back to Top](#reimbursement-submission)

---

# Time Tracking

| Phase | Estimated | Actual |
| ---------------------------------------------------- | --------- | ------- |
| IDE Setup + Installation + Environment Configuration | 1.5 hrs | 1 hr |
| Backend API + DB Setup + Debugging | 3 hrs | 2.5 hrs |
| Angular Frontend UI + Styling + Responsiveness | 2.5 hrs | 2 hrs |
| Documentation | 1 hr | 35 min |

---

# Comments

### a. Assumptions

- There is **no authentication or user-specific filtering**, as the focus is on basic functionality.
- File upload is **optional**, but the date, amount, and description are required fields.
- One-page UI with form + table is sufficient
- File uploads are stored on the server under a local `Uploads/` folder, and links are returned in the response for display.
- No pagination or advanced filtering needed

### b. Problems Encountered & Solutions

- **CORS Issue**: Angular couldn't access the API due to CORS restrictions.
➀ **Solved** by adding a CORS policy in `.NET` and enabling it in `Program.cs`.
- **Database Seeding Failed**: Seeding failed due to `ReceiptFilePath` being non-nullable.
➀ **Solved** by making the property nullable and updating the schema.
- **Incorrect File Links**: File paths didn’t render correctly in the UI.
➀ **Solved** by prefixing paths with the backend base URL in Angular.

### c. Highlights in my Code

- Clean, testable backend architecture (**Controller β†’ Service β†’ DTO ->Repository**)
- The backend is designed with **separation of concerns** using IRepository, IService, and Controller layers.
- Modern Angular app using standalone components
- Real file uploads, database storage, and real-time view updates
- Open for Extension, SOLID principle

[πŸ”Ό Back to Top](#reimbursement-submission)

# Screenshot

Here is the receipt submission UI:

![Receipt Submission UI](screenshot/ui.png)
![Submitted Receipts](screenshot/submittedreceipts.png)

---