diff --git a/README.md b/README.md new file mode 100644 index 0000000..aac6d0d --- /dev/null +++ b/README.md @@ -0,0 +1,107 @@ +# EAMCO Office API + +The **EAMCO Office API** is the central, monolithic backend service for the entire EAMCO office management application. Built with the Flask framework, it serves as the operational hub that powers the day-to-day activities of the business, from customer management to delivery dispatch. + +This application is the "single source of truth" for many core business entities and orchestrates interactions with the other specialized microservices like `eamco_authorize` and `eamco_auto_api`. + +[![Language](https://img.shields.io/badge/Language-Python-blue)](https://www.python.org/) +[![Framework](https://img.shields.io/badge/Framework-Flask-black)](https://flask.palletsprojects.com/) +[![Database](https://img.shields.io/badge/Database-PostgreSQL-blue)](https://www.postgresql.org/) + +--- + +## Core Features + +This is a comprehensive application covering a wide range of business functions, organized into modular components: + +- **Customer Relationship Management (CRM)**: Full lifecycle management of customer data, addresses, and history. +- **Authentication & Authorization**: Secure user login, session management, and role-based access control using `Flask-Login` and `Flask-Bcrypt`. +- **Delivery & Service Hub**: Core logic for scheduling, creating, and tracking oil deliveries and other customer services. +- **Employee Management**: Manages employee profiles, roles, and assignments. +- **Financial & Payment Orchestration**: Integrates with other services to handle payment processing and financial calculations. +- **Reporting & Statistics**: Generates business reports and aggregates data for dashboards. +- **Promotion Engine**: Manages discount codes and promotional offers. +- **Admin Panel**: Provides administrators with tools to manage the entire system. +- **Full-Text Search**: Offers powerful search capabilities across different business domains. + +--- + +## Technical Architecture + +- **Framework**: Built with **Flask**, a powerful and flexible Python web framework. +- **Database**: Uses **PostgreSQL** as its primary data store, with **Flask-SQLAlchemy** as the ORM. +- **Serialization**: Employs **Marshmallow** (`flask-marshmallow`) for robust object serialization and data validation between the database models and the API. +- **Authentication**: Leverages `Flask-Login` for managing user sessions and `Flask-Bcrypt` for secure password hashing. +- **Web Forms**: Uses `Flask-WTF` for handling form submissions, indicating that it may serve some traditional web pages in addition to being a pure JSON API. +- **Deployment**: Production-ready, using `gunicorn` as the WSGI server. The `runProduction.py` script is likely the entry point for a production environment. + +## Getting Started + +### Prerequisites + +- Python 3.10+ +- A running PostgreSQL database. +- A running Redis instance (for `Flask-Session`). + +### Installation + +1. **Clone the repository and navigate into it.** + +2. **Create a virtual environment and install dependencies:** + ```bash + python -m venv venv + source venv/bin/activate + pip install -r requirements.txt + ``` + +3. **Configure your environment:** + The application's configuration is managed by environment variables loaded into the Flask app context. Key settings include `SQLALCHEMY_DATABASE_URI` and `SECRET_KEY`. Refer to the settings files (`settings_*.py`) for details. + +### Running the Service + +#### For Development + +The `app.py` file is configured to run the Flask development server, which provides live reloading. + +```bash +python app.py +``` + +The application will be available at `http://localhost:4056`. + +#### For Production (using Gunicorn) + +The `runProduction.py` script is the intended entry point for production. + +```bash +# Example of running with Gunicorn +gunicorn --bind 0.0.0.0:4056 runProduction:app +``` + +--- + +## Project Structure + +The application is organized into a modular structure, where each directory in `app/` represents a distinct functional domain. + +``` +eamco_office_api/ +├── app/ +│ ├── admin/ +│ ├── auth/ +│ ├── customer/ +│ ├── delivery/ +│ ├── employees/ +│ ├── money/ +│ ├── payment/ +│ ├── reports/ +│ ├── search/ +│ ├── stats/ +│ └── ... (many other modules) +├── app.py # Development server entry point +├── runProduction.py # Production server entry point +├── config.py # Application configuration loading +├── settings_dev.py # Development-specific settings +├── requirements.txt # Python dependencies +└── README.md # This file +``` diff --git a/app/classes/customer.py b/app/classes/customer.py index a153ad0..45f95cc 100755 --- a/app/classes/customer.py +++ b/app/classes/customer.py @@ -98,6 +98,7 @@ class Customer_Description(db.Model): fill_location = db.Column(db.INTEGER) description = db.Column(db.VARCHAR(2000)) + class Customer_Description_schema(ma.SQLAlchemyAutoSchema): class Meta: model = Customer_Description @@ -122,6 +123,8 @@ class Customer_Tank_Inspection(db.Model): tank_status = db.Column(db.BOOLEAN) outside_or_inside = db.Column(db.BOOLEAN) tank_size = db.Column(db.INTEGER) + tank_images = db.Column(db.Integer, default=0) # 0 = false, 1 = true + tank_image_upload_dates = db.Column(db.JSON, default=list) # List of upload dates for each set diff --git a/app/customer/views.py b/app/customer/views.py index 75240d2..d189bba 100755 --- a/app/customer/views.py +++ b/app/customer/views.py @@ -204,40 +204,40 @@ def create_customer(): else: the_state = 'MA' - if response_customer_town == 0: - the_town = 'Auburn' - elif response_customer_state == 1: - the_town = 'Charlton' - elif response_customer_state == 2: - the_town = 'Cherry Valley' - elif response_customer_state == 3: - the_town = 'Dudley' - elif response_customer_state == 4: - the_town = 'Grafton' - elif response_customer_state == 5: - the_town = 'Leicester' - elif response_customer_state == 6: - the_town = 'Millbury' - elif response_customer_state == 7: - the_town = 'N Oxford' - elif response_customer_state == 8: - the_town = 'Oxford' - elif response_customer_state == 9: - the_town = 'Rochdale' - elif response_customer_state == 10: - the_town = 'Shrewsbury' - elif response_customer_state == 11: - the_town = 'Southbridge' - elif response_customer_state == 12: - the_town = 'Spencer' - elif response_customer_state == 13: - the_town = 'Sturbridge' - elif response_customer_state == 14: - the_town = 'Webster' - elif response_customer_state == 15: - the_town = 'Worcester' - else: - the_town = 'NA' + # if response_customer_town == 0: + # the_town = 'Auburn' + # elif response_customer_town == 1: + # the_town = 'Charlton' + # elif response_customer_town == 2: + # the_town = 'Cherry Valley' + # elif response_customer_town == 3: + # the_town = 'Dudley' + # elif response_customer_town == 4: + # the_town = 'Grafton' + # elif response_customer_town == 5: + # the_town = 'Leicester' + # elif response_customer_town == 6: + # the_town = 'Millbury' + # elif response_customer_town == 7: + # the_town = 'N Oxford' + # elif response_customer_town == 8: + # the_town = 'Oxford' + # elif response_customer_town == 9: + # the_town = 'Rochdale' + # elif response_customer_town == 10: + # the_town = 'Shrewsbury' + # elif response_customer_town == 11: + # the_town = 'Southbridge' + # elif response_customer_town == 12: + # the_town = 'Spencer' + # elif response_customer_town == 13: + # the_town = 'Sturbridge' + # elif response_customer_town == 14: + # the_town = 'Webster' + # elif response_customer_town == 15: + # the_town = 'Worcester' + # else: + # the_town = 'NA' geolocator = Nominatim(user_agent="auburnoil") diff --git a/info_paymant_type.txt b/info_paymant_type.txt index c854fd2..b9fa708 100644 --- a/info_paymant_type.txt +++ b/info_paymant_type.txt @@ -1,7 +1,8 @@ 0: Cash 1: CC +11: CC 2: Cash/CC -3: Check + 4: Other @@ -9,5 +10,4 @@ 1: CC - Tiger 11: CC - Authorize 2: Cash/CC -3: Check 4: Other \ No newline at end of file