Compare commits

...

10 Commits

Author SHA1 Message Date
Frank John Begornia
388d02051f Unified email reports
Some checks failed
Deploy Production Email Reports (Unified) / deploy (push) Failing after 11s
2026-01-02 01:20:35 +08:00
Frank John Begornia
d0d82aa8e1 Unified email reports 2026-01-02 01:19:07 +08:00
franknstayn
2e1ad5526c format file and addded new fomr 2020-03-19 23:14:11 +08:00
franknstayn
9bae910d3a Merge branch 'master' of github.com:franknstayn/email_reports 2020-02-29 06:48:49 -06:00
franknstayn
3c58240206 update 2020-02-29 06:48:02 -06:00
franknstayn
4190c957ff added production email 2020-02-29 20:46:34 +08:00
franknstayn
7071fa2eb9 fixed quantity form 2020-02-08 16:32:42 +08:00
franknstayn
74fe447f73 added jersey shorts quantity forms 2020-02-08 16:30:34 +08:00
franknstayn
b0067aeb6e formatted 2019-12-16 19:39:47 +08:00
franknstayn
64b26e494d remove price column 2019-12-05 18:24:51 +08:00
20 changed files with 4627 additions and 847 deletions

8
.dockerignore Normal file
View File

@@ -0,0 +1,8 @@
.git
.gitignore
.env
*.md
docker-compose.yml
.DS_Store
daily_order_reports/*.csv
email.log

23
.env.example Normal file
View File

@@ -0,0 +1,23 @@
# Crew Sportswear Database
DB_HOST_CREW=mysql
DB_PORT_CREW=3306
DB_NAME_CREW=custom_design
DB_USER_CREW=crew_user
DB_PASS_CREW=your_crew_password
# MerchBay Database
DB_HOST_MERCHBAY=mysql
DB_PORT_MERCHBAY=3306
DB_NAME_MERCHBAY=merchbay_laravel
DB_USER_MERCHBAY=merchbay_user
DB_PASS_MERCHBAY=your_merchbay_password
# SMTP Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
# Crew SMTP (mail@crewsportswear.com)
SMTP_PASS_CREW=your_crew_gmail_app_password
# MerchBay SMTP (support@merchbay.com)
SMTP_PASS_MERCHBAY=your_merchbay_gmail_app_password

View File

@@ -0,0 +1,62 @@
name: Build and Push to Registry
on:
push:
tags:
- 'v*'
jobs:
build-push:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Checkout code
shell: sh
run: |
git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git /workspace/repo
cd /workspace/repo
git checkout $GITHUB_REF_NAME
- name: Extract version from tag
shell: sh
run: |
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Build Docker image
shell: sh
run: |
cd /workspace/repo
docker build -t email_reports_crew:${VERSION} .
docker tag email_reports_crew:${VERSION} email_reports_crew:latest
- name: Login to Docker Registry
shell: sh
env:
REGISTRY_URL: ${{ secrets.REGISTRY_URL }}
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
run: |
echo "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin $REGISTRY_URL
- name: Tag and Push images
shell: sh
env:
REGISTRY_URL: ${{ secrets.REGISTRY_URL }}
run: |
docker tag email_reports_crew:${VERSION} ${REGISTRY_URL}/email_reports_crew:${VERSION}
docker tag email_reports_crew:${VERSION} ${REGISTRY_URL}/email_reports_crew:latest
docker push ${REGISTRY_URL}/email_reports_crew:${VERSION}
docker push ${REGISTRY_URL}/email_reports_crew:latest
echo "✓ Pushed images:"
echo " ${REGISTRY_URL}/email_reports_crew:${VERSION}"
echo " ${REGISTRY_URL}/email_reports_crew:latest"
- name: Cleanup
shell: sh
run: |
docker image prune -af
echo "✓ Cleanup completed"

168
.gitea/workflows/deploy.yml Normal file
View File

@@ -0,0 +1,168 @@
name: Deploy Production Email Reports (Unified)
on:
push:
branches:
- main
- master
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Checkout code
shell: sh
run: |
git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git /workspace/repo
cd /workspace/repo
git checkout $GITHUB_REF_NAME
- name: Build Docker image
shell: sh
run: |
cd /workspace/repo
docker build -t email_reports_unified:latest .
docker save email_reports_unified:latest | gzip > email_reports_unified.tar.gz
- name: Setup SSH
shell: sh
env:
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts
- name: Upload image and compose
shell: sh
env:
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
run: |
scp -i ~/.ssh/id_ed25519 \
/workspace/repo/email_reports_unified.tar.gz \
/workspace/repo/docker-compose.yml \
${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/
- name: Deploy on server
shell: sh
env:
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
run: |
ssh -i ~/.ssh/id_ed25519 $DEPLOY_USER@$DEPLOY_HOST << 'EOF'
set -e
DEPLOY_DIR="/var/www/apps/email_reports"
sudo mkdir -p "$DEPLOY_DIR"
sudo chown $USER:$USER "$DEPLOY_DIR"
echo "Loading image"
docker load < /tmp/email_reports_unified.tar.gz
echo "Removing old email_reports images"
docker images | grep email_reports_unified | grep -v "$(docker images email_reports_unified:latest -q)" | awk '{print $3}' | xargs -r docker rmi -f || true
echo "Updating compose file"
cp /tmp/docker-compose.yml "$DEPLOY_DIR/docker-compose.yml"
cd "$DEPLOY_DIR"
echo "Checking .env file"
if [ ! -f .env ]; then
echo ".env file not found at $DEPLOY_DIR/.env"
echo "Please create it first with required variables:"
echo " Crew: DB_HOST_CREW, DB_NAME_CREW, DB_USER_CREW, DB_PASS_CREW, SMTP_PASS_CREW"
echo " MerchBay: DB_HOST_MERCHBAY, DB_NAME_MERCHBAY, DB_USER_MERCHBAY, DB_PASS_MERCHBAY, SMTP_PASS_MERCHBAY"
exit 1
fi
echo "Fixing .env permissions"
sudo chown $USER:$USER .env
sudo chmod 600 .env
echo "Ensure networks"
docker network inspect crew-app-net >/dev/null 2>&1 || \
docker network create crew-app-net
echo "Creating required directories"
mkdir -p daily_order_reports_crew daily_order_reports_merchbay
touch email.log
chmod 666 email.log
chmod 755 daily_order_reports_crew daily_order_reports_merchbay
echo "Stopping existing containers"
docker compose down || true
docker rm -f email_reports_unified email_reports_crew email_reports_merchbay || true
echo "Starting unified container (env vars from .env file)"
docker compose up -d
echo "Waiting for container to start"
sleep 10
if docker ps --format '{{.Names}}' | grep -q email_reports_unified; then
echo "✓ Container is running"
echo "Testing cron daemon"
docker exec email_reports_unified ps aux | grep -q crond && echo "✓ Cron is running"
echo "Cron schedule:"
docker exec email_reports_unified crontab -l
echo "Testing database connectivity (Crew)"
docker exec email_reports_unified ping -c 1 mysql && echo "✓ Can reach MySQL"
else
echo "✗ Container failed to start"
docker compose logs
exit 1
fi
echo "Cleanup"
rm -f /tmp/email_reports_unified.tar.gz /tmp/docker-compose.yml
echo "Docker cleanup"
docker image prune -af --filter "until=24h" || true
docker container prune -f || true
docker system df
echo "✓ Deployment completed!"
echo "Email reports container: email_reports_unified"
echo "Next scheduled runs:"
echo " - Crew: 23:55 CT"
echo " - MerchBay: 23:56 CT"
EOF
- name: Verify deployment
shell: sh
env:
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
run: |
ssh -i ~/.ssh/id_ed25519 $DEPLOY_USER@$DEPLOY_HOST << 'EOF'
echo "Container status:"unified --format "table {{.Names}}\t{{.Status}}\t{{.State}}"
echo ""
echo "Recent logs:"
docker logs --tail 20 email_reports_unified
echo ""
echo "To test manually:"
echo " Crew: docker exec email_reports_unified BRAND=crew php /app/send_report.php"
echo " MerchBay: docker exec email_reports_unified BRAND=merchbay php /app/send_report.php"
echo ""
echo "To view logs:"
echo " docker logs -f email_reports_unified"
echo " docker exec email_reports_unified tail -f /app/email.log"
echo ""
echo "Filter by brand:"
echo " docker exec email_reports_unified grep '[CREW]' /app/email.log"
echo " docker exec email_reports_unified grep '[MERCHBAY]'
echo " docker exec email_reports_crew tail -f /app/email.log"
EOF

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
.env
email.log
daily_order_reports/
daily_order_reports_crew/
daily_order_reports_merchbay/
.DS_Store
phpmailer/

417
DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,417 @@
# Email Reports Deployment Checklist
## Pre-Deployment Setup
### 1. Configure Gitea Secrets
In your Gitea repository **Settings → Secrets**, add:
```
DEPLOY_SSH_KEY = <your-ssh-private-key>
DEPLOY_HOST = <server-ip-or-hostname>
DEPLOY_USER = <ssh-username>
REGISTRY_URL = <docker-registry-url> (optional, for version tags)
REGISTRY_USER = <registry-username> (optional)
REGISTRY_PASSWORD = <registry-password> (optional)
```
### 2. Server Preparation
SSH into your production server:
```bash
ssh user@your-server
# Create deployment directory
sudo mkdir -p /var/www/apps/email_reports
sudo chown $USER:$USER /var/www/apps/email_reports
cd /var/www/apps/email_reports
# Create .env file with production values
vim .env
```
**Required .env variables:**
```env
DB_HOST=mysql # Your MySQL container name
DB_PORT=3306
DB_NAME=custom_design
DB_USER=crew_user
DB_PASS=your_secure_password # CHANGE THIS
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=mail@crewsportswear.com
SMTP_PASS=your_gmail_app_password # Get from Gmail
EMAIL_TO=graphics@crewsportswear.com
EMAIL_BCC=webmaster@crewsportswear.com,angelo@crewsportswear.com,production@crewsportswear.com
APP_URL=https://www.crewsportswear.com
ADMIN_URL=https://admin.crewsportswear.app
```
```bash
# Secure .env
chmod 600 .env
# Create data directories
mkdir -p daily_order_reports
touch email.log
chmod 666 email.log
# Ensure Docker network exists
docker network create crew-app-net || true
```
### 3. Verify MySQL Access
Test database connectivity from server:
```bash
# If MySQL is in a container:
docker exec mysql_container_name mysql -u crew_user -p -e "SHOW DATABASES;"
# Verify network connectivity
docker run --rm --network crew-app-net alpine ping -c 3 mysql
```
### 4. Get Gmail App Password
1. Go to https://myaccount.google.com/apppasswords
2. Create new app password for "Email Reports"
3. Copy the 16-character password
4. Add to `.env` as `SMTP_PASS`
---
## Deployment Workflow
### Option 1: Automated (Recommended)
```bash
# From your local machine
cd email_reports
git add .
git commit -m "Deploy email reports container"
git push origin main
```
Gitea Actions will automatically:
- ✅ Build Docker image
- ✅ Transfer to server
- ✅ Deploy to /var/www/apps/email_reports
- ✅ Start container with cron
- ✅ Verify deployment
Watch the workflow in Gitea: **Actions** tab
### Option 2: Manual Deployment
SSH to server and deploy manually:
```bash
cd /var/www/apps/email_reports
# Pull latest code (if using git on server)
git pull
# Or copy files manually via scp
scp docker-compose.yml user@server:/var/www/apps/email_reports/
# Build and deploy
docker-compose build
docker-compose up -d
# Verify
docker ps | grep email_reports
```
---
## Post-Deployment Verification
### 1. Check Container Status
```bash
# Container is running
docker ps --filter name=email_reports_crew
# Expected output:
# CONTAINER ID IMAGE STATUS NAMES
# abc123... email_reports_crew:latest Up 2 minutes email_reports_crew
```
### 2. Verify Cron is Running
```bash
docker exec email_reports_crew ps aux | grep crond
# Should show: crond -f -l 2
```
### 3. Check Cron Schedule
```bash
docker exec email_reports_crew crontab -l
# Expected output:
# 55 23 * * * cd /app && php index.php >> /var/log/cron.log 2>&1
```
### 4. Test Database Connection
```bash
docker exec email_reports_crew php -r "
\$host = getenv('DB_HOST');
\$db = getenv('DB_NAME');
\$user = getenv('DB_USER');
\$pass = getenv('DB_PASS');
new PDO(\"mysql:host=\$host;dbname=\$db\", \$user, \$pass);
echo 'Database connection: OK\n';
"
```
### 5. Run Manual Test
```bash
# Execute report immediately (don't wait for cron)
docker exec email_reports_crew php /app/index.php
# Check output
docker exec email_reports_crew cat /app/email.log | tail -5
```
Expected log entry:
```
2026-01-02 15:30:00 successfully sent
```
OR
```
2026-01-02 15:30:00 No order for today
```
### 6. Verify Email Sent
Check your inbox at `graphics@crewsportswear.com` for test email.
### 7. Check Logs
```bash
# Container logs
docker logs email_reports_crew
# Cron logs
docker exec email_reports_crew tail -f /var/log/cron.log
# Email execution logs
docker exec email_reports_crew tail -f /app/email.log
# CSV files generated
docker exec email_reports_crew ls -lh /app/daily_order_reports/
```
---
## Monitoring
### View Real-time Logs
```bash
# Follow cron execution
docker logs -f email_reports_crew
# Follow email log
docker exec email_reports_crew tail -f /app/email.log
```
### Check Next Scheduled Run
Cron runs at **23:55 Central Time daily**
```bash
# Current time in container
docker exec email_reports_crew date
# Should show: America/Chicago timezone
docker exec email_reports_crew cat /etc/timezone
```
### Health Check
```bash
# Container health status
docker inspect email_reports_crew | grep -A 5 Health
# Manual health check
docker exec email_reports_crew ps aux | grep crond
```
---
## Troubleshooting
### Container Won't Start
```bash
# View startup logs
docker logs email_reports_crew
# Check compose file
cd /var/www/apps/email_reports
cat docker-compose.yml
# Verify .env exists
ls -la .env
```
### Database Connection Failed
```bash
# Test network connectivity
docker exec email_reports_crew ping mysql
# Verify database credentials in .env
docker exec email_reports_crew env | grep DB_
```
### Email Not Sending
```bash
# Enable debug mode
docker exec email_reports_crew sed -i 's|// \$mail->SMTPDebug = 3;|\$mail->SMTPDebug = 3;|' /app/index.php
# Run manually with debug output
docker exec email_reports_crew php /app/index.php
# Check SMTP credentials
docker exec email_reports_crew env | grep SMTP_
```
### Cron Not Running
```bash
# Check cron daemon
docker exec email_reports_crew ps aux | grep crond
# Restart container
docker restart email_reports_crew
# Verify crontab
docker exec email_reports_crew crontab -l
```
### Wrong Timezone
```bash
# Check timezone
docker exec email_reports_crew date
docker exec email_reports_crew cat /etc/timezone
# Should be: America/Chicago
# If not, rebuild image
```
---
## Rollback
If deployment fails:
```bash
cd /var/www/apps/email_reports
# Stop and remove container
docker-compose down
# Load previous image (if kept)
docker load < /tmp/email_reports_crew_backup.tar.gz
# Or pull from registry
docker pull your-registry/email_reports_crew:previous-version
# Start with old image
docker-compose up -d
```
---
## Deployment Checklist
- [ ] Gitea secrets configured
- [ ] Server directory created: `/var/www/apps/email_reports`
- [ ] `.env` file created with all variables
- [ ] Database credentials tested
- [ ] Gmail app password obtained and configured
- [ ] Docker network `crew-app-net` exists
- [ ] Code pushed to `main` branch (triggers workflow)
- [ ] Workflow completed successfully (green checkmark)
- [ ] Container is running: `docker ps | grep email_reports`
- [ ] Cron is running: `ps aux | grep crond`
- [ ] Manual test executed successfully
- [ ] Email received by recipients
- [ ] Logs showing successful execution
- [ ] Scheduled for next automatic run at 23:55 CT
---
## For MerchBay Reports
Repeat the same process in a separate directory:
```bash
# On server
sudo mkdir -p /var/www/apps/email_reports_merchbay
# ... follow same steps with merchbay database/credentials
```
---
## Maintenance
### Update Recipients
```bash
# Edit .env on server
cd /var/www/apps/email_reports
vim .env
# Update EMAIL_TO or EMAIL_BCC
# Then restart container
docker-compose restart
```
### Change Schedule
Edit Dockerfile, rebuild, and redeploy:
```dockerfile
# Change from 23:55 to 22:00
RUN echo "0 22 * * * cd /app && php index.php" > /etc/crontabs/root
```
### View Historical Reports
```bash
# List all generated CSVs
docker exec email_reports_crew ls -lh /app/daily_order_reports/
# Download specific report
docker cp email_reports_crew:/app/daily_order_reports/daily_order_report_2026-01-02.csv .
```
---
## Success Criteria
✅ Container running continuously
✅ Cron daemon active
✅ Database connectivity confirmed
✅ Manual test sends email
✅ Recipients receive reports
✅ CSV files generated in `/app/daily_order_reports/`
✅ Logs show execution history
✅ Scheduled to run at 23:55 CT daily
**Deployment Complete! 🎉**

39
Dockerfile Normal file
View File

@@ -0,0 +1,39 @@
FROM php:7.4-cli-alpine
# Install dependencies
RUN apk add --no-cache \
dcron \
mysql-client \
&& docker-php-ext-install pdo pdo_mysql
# Set timezone
RUN apk add --no-cache tzdata && \
cp /usr/share/zoneinfo/America/Chicago /etc/localtime && \
echo "America/Chicago" > /etc/timezone && \
apk del tzdata
# Create app directory
WORKDIR /app
# Copy email reports scripts
COPY . /app/
# Create reports directories
RUN mkdir -p /app/daily_order_reports_crew /app/daily_order_reports_merchbay && \
chmod 755 /app/daily_order_reports_crew /app/daily_order_reports_merchbay
# Create crontab with both reports
RUN echo "55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1" > /etc/crontabs/root && \
echo "56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1" >> /etc/crontabs/root && \
chmod 0644 /etc/crontabs/root
# Create log file
RUN touch /var/log/cron.log && \
chmod 666 /var/log/cron.log
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD ps aux | grep -v grep | grep -q crond || exit 1
# Start cron in foreground
CMD crond -f -l 2

324
MIGRATION.md Normal file
View File

@@ -0,0 +1,324 @@
# Migration to Unified Email Reports
## Summary
**Merged `email_reports` and `email_reports_merchbay` into ONE container**
**Before:**
- Two separate directories
- Two separate containers
- Two separate cron jobs calling via HTTP
**After:**
- Single unified container
- Handles both Crew & MerchBay
- Two cron jobs (23:55, 23:56) running internally
- No HTTP calls needed
---
## What Changed
### New Unified Architecture
```
email_reports/
├── send_report.php # NEW: Unified script for both brands
├── index.php # KEPT: Legacy Crew script (backward compatible)
├── Dockerfile # UPDATED: Runs both cron jobs
├── docker-compose.yml # UPDATED: Unified container config
├── .env.example # UPDATED: Both Crew + MerchBay vars
└── .gitea/workflows/
└── deploy.yml # UPDATED: Deploys unified container
```
### Key Changes
1. **send_report.php** - Brand-agnostic report generator
- Uses `BRAND` environment variable (`crew` or `merchbay`)
- Auto-selects database, SMTP, recipients per brand
- Writes to separate CSV directories
2. **Cron Jobs** - Two jobs in one container:
```cron
55 23 * * * BRAND=crew php /app/send_report.php
56 23 * * * BRAND=merchbay php /app/send_report.php
```
3. **Separate CSV Directories**:
- `daily_order_reports_crew/`
- `daily_order_reports_merchbay/`
4. **Unified Logs** - Single `email.log` with brand prefixes:
```
2026-01-02 23:55:00 [CREW] successfully sent (5 orders)
2026-01-02 23:56:00 [MERCHBAY] No order for today
```
---
## Migration Steps
### 1. Server Preparation
SSH to your production server:
```bash
ssh user@server
cd /var/www/apps/email_reports
# Backup existing setup
tar -czf email_reports_backup_$(date +%Y%m%d).tar.gz \
daily_order_reports/ email.log .env
# Create new directories
mkdir -p daily_order_reports_crew daily_order_reports_merchbay
# Move existing Crew reports (optional)
mv daily_order_reports/* daily_order_reports_crew/ 2>/dev/null || true
```
### 2. Update .env File
Replace your `.env` with unified configuration:
```bash
cd /var/www/apps/email_reports
cat > .env << 'EOL'
# Crew Sportswear Database
DB_HOST_CREW=mysql
DB_PORT_CREW=3306
DB_NAME_CREW=custom_design
DB_USER_CREW=crew_user
DB_PASS_CREW=your_crew_password
# MerchBay Database
DB_HOST_MERCHBAY=mysql
DB_PORT_MERCHBAY=3306
DB_NAME_MERCHBAY=merchbay_laravel
DB_USER_MERCHBAY=merchbay_user
DB_PASS_MERCHBAY=your_merchbay_password
# SMTP Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
# Crew SMTP (mail@crewsportswear.com)
SMTP_PASS_CREW=your_crew_gmail_app_password
# MerchBay SMTP (support@merchbay.com)
SMTP_PASS_MERCHBAY=your_merchbay_gmail_app_password
EOL
chmod 600 .env
```
### 3. Remove Old Cron Jobs
If you had host-level cron jobs calling via HTTP:
```bash
crontab -e
# REMOVE these lines:
# 55 23 * * * wget -qO- https://www.crewsportswear.com/email_reports/index.php &> /dev/null
# 55 23 * * * wget -qO- https://www.crewsportswear.com/email_reports_merchbay/index.php &> /dev/null
```
**The container now handles scheduling internally!**
### 4. Deploy Unified Container
```bash
# From your local machine
cd email_reports
git add .
git commit -m "Migrate to unified email reports container"
git push origin main
```
Gitea workflow will automatically:
- Build unified image
- Deploy to server
- Start container with both cron jobs
### 5. Verify Deployment
```bash
# On server
docker ps | grep email_reports
# Should show:
# email_reports_unified Up X minutes
# Check cron schedule
docker exec email_reports_unified crontab -l
# Expected output:
# 55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1
# 56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1
```
### 6. Test Both Reports
```bash
# Test Crew report
docker exec email_reports_unified BRAND=crew php /app/send_report.php
# Test MerchBay report
docker exec email_reports_unified BRAND=merchbay php /app/send_report.php
# Check logs
docker exec email_reports_unified tail /app/email.log
# Expected:
# 2026-01-02 15:30:00 [CREW] successfully sent
# 2026-01-02 15:30:15 [MERCHBAY] successfully sent
```
### 7. Verify Email Delivery
- Check `graphics@crewsportswear.com` inbox
- Should receive **two separate emails**:
- "CREW Daily Order Report - 2026-01-02"
- "Merchbay Daily Order Report - 2026-01-02"
---
## What to Delete
### On Server
```bash
# The old email_reports_merchbay directory is no longer needed
# (if it exists on the server)
rm -rf /var/www/apps/email_reports_merchbay
# Old container (will be removed automatically by deployment)
docker rm -f email_reports_crew email_reports_merchbay
```
### In Git Repository
The `email_reports_merchbay/` directory in your repos can stay for reference, or archive it:
```bash
cd /path/to/repos
tar -czf email_reports_merchbay_archive.tar.gz email_reports_merchbay/
# Optional: rm -rf email_reports_merchbay/
```
---
## Troubleshooting
### Both Reports Not Running
```bash
# Check crontab
docker exec email_reports_unified crontab -l
# Manually trigger both
docker exec email_reports_unified BRAND=crew php /app/send_report.php
docker exec email_reports_unified BRAND=merchbay php /app/send_report.php
```
### MerchBay Database Connection Failed
```bash
# Verify MerchBay DB credentials in .env
docker exec email_reports_unified env | grep MERCHBAY
# Test connection
docker exec email_reports_unified php -r "
new PDO(
'mysql:host=' . getenv('DB_HOST_MERCHBAY') . ';dbname=' . getenv('DB_NAME_MERCHBAY'),
getenv('DB_USER_MERCHBAY'),
getenv('DB_PASS_MERCHBAY')
);
echo 'MerchBay DB: OK\n';
"
```
### Only One Email Received
```bash
# Check which brand succeeded
docker exec email_reports_unified grep "$(date +%Y-%m-%d)" /app/email.log
# Look for [CREW] or [MERCHBAY] prefixes
# If one failed, check the error message
```
### CSV Files Not Created
```bash
# Check directories exist
docker exec email_reports_unified ls -la /app/ | grep daily_order
# Should show:
# daily_order_reports_crew/
# daily_order_reports_merchbay/
# Check permissions
docker exec email_reports_unified stat -c '%a' /app/daily_order_reports_crew
# Should be 755
```
---
## Rollback Plan
If something goes wrong:
```bash
# On server
cd /var/www/apps/email_reports
# Stop unified container
docker compose down
# Restore backup
tar -xzf email_reports_backup_YYYYMMDD.tar.gz
# Restore old .env
# Start old container
```
---
## Benefits of Unified Container
**Simpler Infrastructure**
- One container instead of two
- Single deployment process
- Shared codebase
**Better Resource Usage**
- One cron daemon
- Shared Docker image
- Less memory overhead
**Easier Maintenance**
- Update both brands at once
- Unified logging
- Single point of monitoring
**Consistent Behavior**
- Same PHPMailer version
- Same PHP version
- Same timezone handling
---
## Next Steps
1. ✅ Deploy unified container
2. ✅ Test both reports manually
3. ✅ Wait for automatic execution at 23:55/23:56
4. ✅ Verify emails received
5. ✅ Monitor logs for first week
6. ✅ Remove old cron jobs
7. ✅ Archive old email_reports_merchbay directory
**Migration Complete! 🎉**

467
README.md Normal file
View File

@@ -0,0 +1,467 @@
# Email Reports - Dockerized Container
Unified Docker container for automated daily order email reports for **both Crew Sportswear and MerchBay**.
## Overview
This container runs cron jobs daily at **23:55 CT** to:
1. Query orders from both Crew and MerchBay databases
2. Generate separate CSV reports for each brand
3. Email reports to recipients via SMTP
**Cron Schedule:**
- **23:55** - Crew Sportswear report
- **23:56** - MerchBay report
## Quick Start
### 1. Create `.env` file
```bash
cp .env.example .env
vim .env
```
Configure your environment variables:
```env
# Crew Database
DB_HOST_CREW=mysql
DB_NAME_CREW=custom_design
DB_USER_CREW=crew_user
DB_PASS_CREW=your_password
# MerchBay Database
DB_HOST_MERCHBAY=mysql
DB_NAME_MERCHBAY=merchbay_laravel
DB_USER_MERCHBAY=merchbay_user
DB_PASS_MERCHBAY=your_password
# SMTP
SMTP_PASS_CREW=crew_gmail_app_password
SMTP_PASS_MERCHBAY=merchbay_gmail_app_password
```
### 2. Build and Run
```bash
# Build image
docker-compose build
# Start container
docker-compose up -d
# Check logs
docker logs -f email_reports_crew
```
### 3. Test Manually
```bash
# Test Crew report
docker exec email_reports_unified BRAND=crew php /app/send_report.php
# Test MerchBay report
docker exec email_reports_unified BRAND=merchbay php /app/send_report.php
# Check cron log
docker exec email_reports_unified tail -f /var/log/cron.log
# Check email log (shows both brands)
docker exec email_reports_unified tail -f /app/email.log
```
┌──────────────────────────────────────────┐
│ Email Reports Container (Unified) │
│ │
│ ┌────────────────────────────────────┐ │
│ │ Cron Jobs: │ │
│ │ 23:55 → BRAND=crew │ │
│ │ 23:56 → BRAND=merchbay │ │
│ │ │ │
│ │ send_report.php │ │
│ │ └─ PHPMailer │ │
│ └────────────────────────────────────┘ │
│ │ │
└─────────────┼────────────────────────────┘
├──> MySQL: custom_design (Crew)
├──> MySQL: merchbay_laravel (MerchBay)
└──> SMTP: Gmail (2 accounts)
├──────> MySQL (crew-app-net)
└──────> SMTP (smtp.gmail.com)
```
## Fsend_report.php** - Unified report generator (handles both brands)
- **index.php** - Legacy Crew report (kept for backward compatibility)
- **dbconfig.php** - Database connection (env-aware)
- **phpmailer/** - Email library
## Cron Schedule
```cron
55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1
56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1
```
**23:55 CT** - Crew Sportswear
**23:56 CT** - MerchBay
Both run daily, 1 minute apart.
55 23 * * * cd /app && php index.php >> /var/log/cron.log 2>&1
```
Runs daily at **11:55 PM Central Time**
## Environment Variables
### Crew Sportswear
| Variable | Default | Description |
|----------|---------|-------------|
| DB_HOST_CREW | mysql | MySQL host for Crew |
| DB_PORT_CREW | 3306 | MySQL port |
| DB_NAME_CREW | custom_design | Crew database name |
| DB_USER_CREW | crew_user | Crew database username |
| DB_PASS_CREW | - | Crew database password |
| SMTP_PASS_CREW | - | Gmail app password for mail@crewsportswear.com |
### MerchBay
| Variable | Default | Description |
|----------|---------|-------------|
| DB_HOST_MERCHBAY | mysql | MySQL host for MerchBay |
| DB_PORT_MERCHBAY | 3306 | MySQL port |
| DB_NAME_MERCHBAY | merchbay_laravel | MerchBay database name |
| DB_USER_MERCHBAY | merchbay_user | MerchBay database username |
| DB_PASS_MERCHBAY | - | MerchBay database password |
| SMTP_PASS_MERCHBAY | - | Gmail app password for support@merchbay.com |
### Shared
| Variable | Default | Description |
|----------|---------|-------------|
| SMTP_HOST | smtp.gmail.com | SMTP server |
| SMTP_PORT | 587 | SMTP port |
## Brand Configuration
The unified container handles both brands using the `BRAND` environment variable:
**Crew Sportswear (`BRAND=crew`)**:
- Database: `custom_design`
- From: `orders@crewsportswear.com`
- To: `graphics@crewsportswear.com`
- BCC: webmaster, angelo, production @crewsportswear.com
- Admin: https://admin.crewsportswear.app
- CSV: `daily_order_reports_crew/`
**MerchBay (`BRAND=merchbay`)**:
- Database: `merchbay_laravel`
- From: `orders@merchbay.com`
- To: `graphics@crewsportswear.com`
- BCC: webmaster, production @crewsportswear.com
- Admin: https://merchbay.app
- CSV: `daily_order_reports_merchbay/`
## Networks
Container must be on **crew-app-net** to access MySQL:
```yaml
networks:
- crew-app-net
networks:
crew-app-net:
external: true
```
Create network if it doesn't exist:
```bash
docker network create crew-app-net
```
## Volumes
```yaml
volumes:
- ./daily_order_reports_crew:/app/daily_order_reports_crew # Crew CSV archives
- ./daily_order_reports_merchbay:/app/daily_order_reports_merchbay # MerchBay CSV archives
- ./email.log:/app/email.log # Combined execution log
```
Both brands write to the same `email.log` with prefixes `[CREW]` and `[MERCHBAY]`.
## Deployment
### Automated Deployment (Gitea Actions)
**Production deployment** is automated via Gitea Actions when pushing to `main` or `master` branch.
```bash
# Trigger deployment
git add .
git commit -m "Update email reports"
git push origin main
```
The workflow will:
1. Build Docker image
2. Transfer to production server via SSH
3. Deploy to `/var/www/apps/email_reports`
4. Start container with cron
5. Verify container is running
**Registry build** is triggered by version tags:
```bash
# Create version tag
git tag v1.0.0
git push origin v1.0.0
```
This builds and pushes to your Docker registry.
### Manual Deployment
```bash
# Deploy via docker-compose
docker-compose up -d --build
# Or build specific image version
docker build -t email-reports:1.0.0 .
docker tag email-reports:1.0.0 your-registry/email-reports:1.0.0
docker push your-registry/email-reports:1.0.0
```
### Required Gitea Secrets
Configure in your repository settings:
- `DEPLOY_SSH_KEY` - SSH private key for deployment server
- `DEPLOY_HOST` - Deployment server hostname/IP
- `DEPLOY_USER` - SSH username
- `REGISTRY_URL` - Docker registry URL (for version tags)
- `REGISTRY_USER` - Registry username
- `REGISTRY_PASSWORD` - Registry password
### Server Setup (First Time)
On your production server, create the deployment directory and `.env` file:
```bash
# Create directory
sudo mkdir -p /var/www/apps/email_reports
sudo chown $USER:$USER /var/www/apps/email_reports
cd /var/www/apps/email_reports
# Create .env file
cat > .env << 'EOL'
DB_HOST=mysql
DB_PORT=3306
DB_NAME=custom_design
DB_USER=crew_user
DB_PASS=your_secure_password
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=mail@crewsportswear.com
SMTP_PASS=your_gmail_app_password
EMAIL_TO=graphics@crewsportswear.com
EMAIL_BCC=webmaster@crewsportswear.com,angelo@crewsportswear.com,production@crewsportswear.com
APP_URL=https://www.crewsportswear.com
ADMIN_URL=https://admin.crewsportswear.app
EOL
chmod 600 .env
# Create data directories
mkdir -p daily_order_reports
touch email.log
chmod 666 email.log
# Ensure network exists
docker network create crew-app-net || true
```
Now push to trigger the first deployment!
### Multiple Instances
For MerchBay, create similar setup in `email_reports_merchbay/`:
```yaml
# docker-compose.yml in email_reports_merchbay/
services:
email-reports-merchbay:
build: .
container_name: email_reports_merchbay
environment:
- DB_NAME=merchbay_db
- EMAIL_TO=orders@merchbay.com
# ... other env vars
```
## Monitoring
### Check Container Health
```bash
# Container status
docker ps | grep email_reports
# Should show email_reports_unified
# Health check
docker inspect email_reports_unified | grep -A 5 Health
```
### View Logs
```bash
# Real-time cron logs (both brands)
docker exec email_reports_unified tail -f /var/log/cron.log
# Email execution logs (prefixed by brand)
docker exec email_reports_unified tail -f /app/email.log
# Example log output:
# 2026-01-02 23:55:00 [CREW] successfully sent (5 orders)
# 2026-01-02 23:56:00 [MERCHBAY] No order for today
# Last 50 lines
docker logs --tail 50 email_reports_unified
# Filter by brand
docker exec email_reports_unified grep "\[CREW\]" /app/email.log | tail -10
docker exec email_reports_unified grep "\[MERCHBAY\]" /app/email.log | tail -10
```
### Verify Cron Schedule
```bash
# View active crontab (should show both jobs)
docker exec email_reports_unified crontab -l
# Expected:
# 55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1
# 56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1
# Check if cron is running
docker exec email_reports_unified ps aux | grep crond
```
## Troubleshooting
### Database Connection Failed
```bash
# Test MySQL connectivity
docker exec email_reports_crew ping mysql
# Test database connection
docker exec email_reports_crew php -r "new PDO('mysql:host=mysql;dbname=custom_design', 'user', 'pass');"
# Check network
docker network inspect crew-app-net
```
### Email Not Sending
```bash
# Enable debug mode
docker exec email_reports_crew sed -i 's|// \$mail->SMTPDebug|\$mail->SMTPDebug|' /app/index.php
# Run manually with debug
docker exec email_reports_crew php /app/index.php
# Check SMTP credentials in .env
```
### Cron Not Running
```bash
# Check cron daemon
docker exec email_reports_crew ps aux | grep crond
# Restart container
docker restart email_reports_crew
# View crontab
docker exec email_reports_crew cat /etc/crontabs/root
```
### Wrong Timezone
```bash
# Verify timezone
docker exec email_reports_crew date
docker exec email_reports_crew cat /etc/timezone
# Should show: America/Chicago
```
### Permissions Issues
```bash
# Fix CSV directory permissions
docker exec email_reports_crew chmod 755 /app/daily_order_reports
# Fix log file
docker exec email_reports_crew chmod 666 /app/email.log
```
## Maintenance
### Update Cron Schedule
Edit Dockerfile and rebuild:
```dockerfile
RUN echo "30 22 * * * cd /app && php index.php" > /etc/crontabs/root
```
### Rotate Logs
```bash
# Manually clear logs (optional)
docker exec email_reports_crew truncate -s 0 /var/log/cron.log
docker exec email_reports_crew truncate -s 0 /app/email.log
```
### Backup Reports
```bash
# Archive old CSV files
tar -czf daily_reports_backup_$(date +%Y%m%d).tar.gz daily_order_reports/
# Or sync to S3/backup location
```
## Security
1. **Never commit `.env`** - Use `.env.example` only
2. **Use Gmail App Passwords** - Not your main password
3. **Restrict network access** - Only join necessary networks
4. **Rotate credentials** - Change passwords regularly
5. **Monitor logs** - Check for unauthorized access
## Advantages of Separate Container
**Isolation** - Reports run independently of web apps
**Reusability** - Can serve multiple apps (Crew + MerchBay)
**Simple Deployment** - Single purpose, easy to update
**Resource Control** - Limit CPU/memory for cron jobs
**Independent Scaling** - Restart without affecting web traffic
**Clean Separation** - No coupling with Laravel/framework
## Next Steps
1. Test database connectivity
2. Verify SMTP credentials
3. Run manual test: `docker exec email_reports_crew php /app/index.php`
4. Wait for 23:55 or adjust cron for testing
5. Monitor logs for first automated run
6. Set up similar container for MerchBay reports

View File

@@ -1,22 +0,0 @@
StoreName,ProductName,NAME,NUMBER,Size,JerseySize,ShortsSize,Price,Quantity,TotalPrice,Tax,DateCreated,InvoiceNumber,Payer_Email
"World Class Basketball",Socks,,,,,,12.00,2,24,2.4000000000000004,"2019-03-13 14:11:35",2019-5c8958991de3a,
"World Class Basketball","Illinois Sleeveless Hoodie",,,M,,,25.00,1,25,2.5,"2019-03-13 14:14:14",2019-5c8958991de3a,
"World Class Basketball","Wisconsin Long Sleeve",,,L,,,25.00,1,25,2.5,"2019-03-13 14:15:48",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,44,,YXL,YXL,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,3,,YXL,YXL,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,15,,M,M,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,11,,S,S,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,0,,YL,YL,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,2,,S,S,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,5,,YXL,YXL,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,20,,YL,YL,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Away Uniform",,4,,YL,YL,40.00,1,40,4,"2019-03-13 14:18:57",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,15,,M,M,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,11,,S,S,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,0,,YL,YL,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,2,,S,S,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,5,,YXL,YXL,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,20,,YL,YL,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,4,,YL,YL,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,44,,YXL,YXL,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
"World Class Basketball","Illinois Home Uniform",,3,,YXL,YXL,40.00,1,40,4,"2019-03-13 14:22:29",2019-5c8958991de3a,
1 StoreName ProductName NAME NUMBER Size JerseySize ShortsSize Price Quantity TotalPrice Tax DateCreated InvoiceNumber Payer_Email
2 World Class Basketball Socks 12.00 2 24 2.4000000000000004 2019-03-13 14:11:35 2019-5c8958991de3a
3 World Class Basketball Illinois Sleeveless Hoodie M 25.00 1 25 2.5 2019-03-13 14:14:14 2019-5c8958991de3a
4 World Class Basketball Wisconsin Long Sleeve L 25.00 1 25 2.5 2019-03-13 14:15:48 2019-5c8958991de3a
5 World Class Basketball Illinois Away Uniform 44 YXL YXL 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
6 World Class Basketball Illinois Away Uniform 3 YXL YXL 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
7 World Class Basketball Illinois Away Uniform 15 M M 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
8 World Class Basketball Illinois Away Uniform 11 S S 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
9 World Class Basketball Illinois Away Uniform 0 YL YL 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
10 World Class Basketball Illinois Away Uniform 2 S S 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
11 World Class Basketball Illinois Away Uniform 5 YXL YXL 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
12 World Class Basketball Illinois Away Uniform 20 YL YL 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
13 World Class Basketball Illinois Away Uniform 4 YL YL 40.00 1 40 4 2019-03-13 14:18:57 2019-5c8958991de3a
14 World Class Basketball Illinois Home Uniform 15 M M 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
15 World Class Basketball Illinois Home Uniform 11 S S 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
16 World Class Basketball Illinois Home Uniform 0 YL YL 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
17 World Class Basketball Illinois Home Uniform 2 S S 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
18 World Class Basketball Illinois Home Uniform 5 YXL YXL 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
19 World Class Basketball Illinois Home Uniform 20 YL YL 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
20 World Class Basketball Illinois Home Uniform 4 YL YL 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
21 World Class Basketball Illinois Home Uniform 44 YXL YXL 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a
22 World Class Basketball Illinois Home Uniform 3 YXL YXL 40.00 1 40 4 2019-03-13 14:22:29 2019-5c8958991de3a

View File

@@ -1,180 +0,0 @@
StoreName,ProductName,NAME,NUMBER,Size,JerseySize,ShortsSize,Price,Quantity,TotalPrice,Tax,DateCreated,InvoiceNumber,Payer_Email
Limitless,"Black Uniform",,12,,S,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,11,,YXL,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,6,,S,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,30,,YXL,YXL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,30,,S,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,15,,YXL,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,25,,S,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,1,,YXS,YS,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,8,,M,YXL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,18,,YM,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,0,,M,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,6,,YL,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,23,,M,XL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,17,,YL,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,1,,L,YXL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,7,,YL,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,13,,YL,YM,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,0,,S,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,4,,S,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,21,,YXL,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,0,,YXL,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,34,,S,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,10,,YXL,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,67,,S,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,3,,YXL,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,11,,M,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,29,,YXS,YM,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,7,,M,L,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,23,,YM,YS,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,7,,M,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,53,,YL,YXL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,10,,M,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,21,,YL,L,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,24,,L,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,2,,YL,L,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,27,,XL,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,23,,S,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,21,,S,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,23,,YXL,YXL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,33,,YXL,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,8,,S,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,11,,YXL,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,54,,S,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,7,,YXL,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,9,,M,YM,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,5,,YM,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,34,,M,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,10,,YM,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,2,,M,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,17,,YL,YL,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,0,,L,YS,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,0,,YL,M,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,19,,YL,YM,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Black Uniform",,34,,XL,S,45.00,1,45,4.5,"2019-08-31 22:22:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,22,L,,,25.00,1,25,2.5,"2019-08-31 22:27:51",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,40,L,,,25.00,1,25,2.5,"2019-08-31 22:27:51",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,34,L,,,25.00,1,25,2.5,"2019-08-31 22:28:24",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,5,L,,,25.00,1,25,2.5,"2019-08-31 22:28:24",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,1,L,,,25.00,1,25,2.5,"2019-08-31 22:29:26",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,24,L,,,25.00,1,25,2.5,"2019-08-31 22:29:26",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,5,M,,,25.00,1,25,2.5,"2019-08-31 22:33:16",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,0,L,,,25.00,1,25,2.5,"2019-08-31 22:33:16",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,42,M,,,25.00,1,25,2.5,"2019-08-31 22:35:11",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,35,M,,,25.00,1,25,2.5,"2019-08-31 22:35:11",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,21,M,,,25.00,1,25,2.5,"2019-08-31 22:35:44",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,21,M,,,25.00,1,25,2.5,"2019-08-31 22:35:44",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,12,M,,,25.00,1,25,2.5,"2019-08-31 22:36:13",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,9,M,,,25.00,1,25,2.5,"2019-08-31 22:36:13",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,4,M,,,25.00,1,25,2.5,"2019-08-31 22:36:29",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,4,M,,,25.00,1,25,2.5,"2019-08-31 22:36:29",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,10,M,,,25.00,1,25,2.5,"2019-08-31 22:40:17",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,42,M,,,25.00,1,25,2.5,"2019-08-31 22:40:17",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,2,M,,,25.00,1,25,2.5,"2019-08-31 22:40:56",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,M,,,25.00,1,25,2.5,"2019-08-31 22:40:56",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,7,M,,,25.00,1,25,2.5,"2019-08-31 22:42:48",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,0,M,,,25.00,1,25,2.5,"2019-08-31 22:42:48",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,7,M,,,25.00,1,25,2.5,"2019-08-31 22:44:29",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,34,M,,,25.00,1,25,2.5,"2019-08-31 22:44:29",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,9,M,,,25.00,1,25,2.5,"2019-08-31 22:45:11",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,8,M,,,25.00,1,25,2.5,"2019-08-31 22:45:11",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,11,M,,,25.00,1,25,2.5,"2019-08-31 22:45:59",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,35,S,,,25.00,1,25,2.5,"2019-08-31 22:45:59",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,33,S,,,25.00,1,25,2.5,"2019-08-31 22:47:01",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,3,S,,,25.00,1,25,2.5,"2019-08-31 22:47:01",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,S,,,25.00,1,25,2.5,"2019-08-31 22:47:29",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,8,S,,,25.00,1,25,2.5,"2019-08-31 22:47:29",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,15,S,,,25.00,1,25,2.5,"2019-08-31 22:48:30",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,S,,,25.00,1,25,2.5,"2019-08-31 22:48:30",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,20,S,,,25.00,1,25,2.5,"2019-08-31 22:49:02",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,1,S,,,25.00,1,25,2.5,"2019-08-31 22:49:02",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,12,S,,,25.00,1,25,2.5,"2019-08-31 22:49:42",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,31,S,,,25.00,1,25,2.5,"2019-08-31 22:49:42",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,11,S,,,25.00,1,25,2.5,"2019-08-31 22:50:16",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,9,S,,,25.00,1,25,2.5,"2019-08-31 22:50:16",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,5,S,,,25.00,1,25,2.5,"2019-08-31 22:51:24",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,1,S,,,25.00,1,25,2.5,"2019-08-31 22:51:24",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,35,S,,,25.00,1,25,2.5,"2019-08-31 22:51:59",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,1,S,,,25.00,1,25,2.5,"2019-08-31 22:51:59",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,14,S,,,25.00,1,25,2.5,"2019-08-31 22:52:28",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,0,S,,,25.00,1,25,2.5,"2019-08-31 22:52:28",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,12,S,,,25.00,1,25,2.5,"2019-08-31 22:53:20",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,25,S,,,25.00,1,25,2.5,"2019-08-31 22:53:20",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,67,S,,,25.00,1,25,2.5,"2019-08-31 22:56:45",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,54,S,,,25.00,1,25,2.5,"2019-08-31 22:56:45",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,8,S,,,25.00,1,25,2.5,"2019-08-31 22:58:19",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,30,S,,,25.00,1,25,2.5,"2019-08-31 22:58:19",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,34,S,,,25.00,1,25,2.5,"2019-08-31 23:09:10",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,6,S,,,25.00,1,25,2.5,"2019-08-31 23:09:10",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,4,S,,,25.00,1,25,2.5,"2019-08-31 23:09:44",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,21,S,,,25.00,1,25,2.5,"2019-08-31 23:09:44",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,S,,,25.00,1,25,2.5,"2019-08-31 23:11:18",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,12,S,,,25.00,1,25,2.5,"2019-08-31 23:11:18",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,0,S,,,25.00,1,25,2.5,"2019-08-31 23:11:57",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,26,XL,,,25.00,1,25,2.5,"2019-08-31 23:11:57",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,34,XL,,,25.00,1,25,2.5,"2019-08-31 23:13:25",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,2,XL,,,25.00,1,25,2.5,"2019-08-31 23:13:25",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,11,XL,,,25.00,1,25,2.5,"2019-08-31 23:13:55",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,20,XL,,,25.00,1,25,2.5,"2019-08-31 23:13:55",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,34,XL,,,25.00,1,25,2.5,"2019-08-31 23:15:34",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,27,XL,,,25.00,1,25,2.5,"2019-08-31 23:15:34",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,15,YL,,,25.00,1,25,2.5,"2019-08-31 23:16:17",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,3,YL,,,25.00,1,25,2.5,"2019-08-31 23:16:17",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,28,YL,,,25.00,1,25,2.5,"2019-08-31 23:16:59",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,0,YL,,,25.00,1,25,2.5,"2019-08-31 23:16:59",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,2,YL,,,25.00,1,25,2.5,"2019-08-31 23:18:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,36,YL,,,25.00,1,25,2.5,"2019-08-31 23:18:38",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,13,YL,,,25.00,1,25,2.5,"2019-08-31 23:19:09",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,22,YL,,,25.00,1,25,2.5,"2019-08-31 23:19:09",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,22,YL,,,25.00,1,25,2.5,"2019-08-31 23:20:11",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,10,YL,,,25.00,1,25,2.5,"2019-08-31 23:20:11",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,33,YL,,,25.00,1,25,2.5,"2019-08-31 23:20:57",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,30,YL,,,25.00,1,25,2.5,"2019-08-31 23:20:57",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,30,YL,,,25.00,1,25,2.5,"2019-08-31 23:21:28",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,33,YL,,,25.00,1,25,2.5,"2019-08-31 23:21:28",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,21,YL,,,25.00,1,25,2.5,"2019-08-31 23:22:05",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,30,YL,,,25.00,1,25,2.5,"2019-08-31 23:22:05",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,19,YL,,,25.00,1,25,2.5,"2019-08-31 23:22:43",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,13,YL,,,25.00,1,25,2.5,"2019-08-31 23:22:43",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,2,YL,,,25.00,1,25,2.5,"2019-08-31 23:23:07",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,7,YL,,,25.00,1,25,2.5,"2019-08-31 23:23:07",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,21,YL,,,25.00,1,25,2.5,"2019-08-31 23:24:00",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,0,YL,,,25.00,1,25,2.5,"2019-08-31 23:24:00",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,17,YL,,,25.00,1,25,2.5,"2019-08-31 23:24:33",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,17,YL,,,25.00,1,25,2.5,"2019-08-31 23:24:33",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,53,YL,,,25.00,1,25,2.5,"2019-08-31 23:25:07",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,6,YL,,,25.00,1,25,2.5,"2019-08-31 23:25:07",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,5,YM,,,25.00,1,25,2.5,"2019-08-31 23:25:33",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,3,YM,,,25.00,1,25,2.5,"2019-08-31 23:25:33",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,33,YM,,,25.00,1,25,2.5,"2019-08-31 23:26:05",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,YM,,,25.00,1,25,2.5,"2019-08-31 23:26:05",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,8,YM,,,25.00,1,25,2.5,"2019-08-31 23:26:49",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,34,YM,,,25.00,1,25,2.5,"2019-08-31 23:26:49",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,YM,,,25.00,1,25,2.5,"2019-08-31 23:27:19",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,2,YM,,,25.00,1,25,2.5,"2019-08-31 23:27:19",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,10,YM,,,25.00,1,25,2.5,"2019-08-31 23:27:51",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,28,YM,,,25.00,1,25,2.5,"2019-08-31 23:27:51",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,18,YM,,,25.00,1,25,2.5,"2019-08-31 23:29:05",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,YM,,,25.00,1,25,2.5,"2019-08-31 23:29:05",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,5,YM,,,25.00,1,25,2.5,"2019-08-31 23:29:36",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,29,YS,,,25.00,1,25,2.5,"2019-08-31 23:31:02",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,5,YS,,,25.00,1,25,2.5,"2019-08-31 23:31:19",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,1,YS,,,25.00,1,25,2.5,"2019-08-31 23:31:47",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,21,YXL,,,25.00,1,25,2.5,"2019-08-31 23:32:15",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,33,YXL,,,25.00,1,25,2.5,"2019-08-31 23:32:15",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,11,YXL,,,25.00,1,25,2.5,"2019-08-31 23:32:45",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,10,YXL,,,25.00,1,25,2.5,"2019-08-31 23:32:45",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,9,YXL,,,25.00,1,25,2.5,"2019-08-31 23:33:24",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,20,YXL,,,25.00,1,25,2.5,"2019-08-31 23:33:24",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,3,YXL,,,25.00,1,25,2.5,"2019-08-31 23:34:02",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,7,YXL,,,25.00,1,25,2.5,"2019-08-31 23:34:02",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,15,YXL,,,25.00,1,25,2.5,"2019-08-31 23:34:28",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,11,YXL,,,25.00,1,25,2.5,"2019-08-31 23:34:28",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,30,YXL,,,25.00,1,25,2.5,"2019-08-31 23:34:55",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,10,YXL,,,25.00,1,25,2.5,"2019-08-31 23:34:55",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,0,YXL,,,25.00,1,25,2.5,"2019-08-31 23:35:27",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,33,YXL,,,25.00,1,25,2.5,"2019-08-31 23:35:27",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,11,YXL,,,25.00,1,25,2.5,"2019-08-31 23:35:56",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,23,YXL,,,25.00,1,25,2.5,"2019-08-31 23:35:56",20190901-0181,dawaun@limitlessbasketball.com
Limitless,"Reversible Jersey",,21,YXL,,,25.00,1,25,2.5,"2019-08-31 23:36:11",20190901-0181,dawaun@limitlessbasketball.com
1 StoreName ProductName NAME NUMBER Size JerseySize ShortsSize Price Quantity TotalPrice Tax DateCreated InvoiceNumber Payer_Email
2 Limitless Black Uniform 12 S S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
3 Limitless Black Uniform 11 YXL S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
4 Limitless Black Uniform 6 S YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
5 Limitless Black Uniform 30 YXL YXL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
6 Limitless Black Uniform 30 S M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
7 Limitless Black Uniform 15 YXL S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
8 Limitless Black Uniform 25 S M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
9 Limitless Black Uniform 1 YXS YS 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
10 Limitless Black Uniform 8 M YXL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
11 Limitless Black Uniform 18 YM YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
12 Limitless Black Uniform 0 M YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
13 Limitless Black Uniform 6 YL M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
14 Limitless Black Uniform 23 M XL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
15 Limitless Black Uniform 17 YL S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
16 Limitless Black Uniform 1 L YXL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
17 Limitless Black Uniform 7 YL M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
18 Limitless Black Uniform 13 YL YM 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
19 Limitless Black Uniform 0 S YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
20 Limitless Black Uniform 4 S M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
21 Limitless Black Uniform 21 YXL YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
22 Limitless Black Uniform 0 YXL M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
23 Limitless Black Uniform 34 S YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
24 Limitless Black Uniform 10 YXL M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
25 Limitless Black Uniform 67 S M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
26 Limitless Black Uniform 3 YXL M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
27 Limitless Black Uniform 11 M M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
28 Limitless Black Uniform 29 YXS YM 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
29 Limitless Black Uniform 7 M L 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
30 Limitless Black Uniform 23 YM YS 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
31 Limitless Black Uniform 7 M S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
32 Limitless Black Uniform 53 YL YXL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
33 Limitless Black Uniform 10 M YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
34 Limitless Black Uniform 21 YL L 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
35 Limitless Black Uniform 24 L S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
36 Limitless Black Uniform 2 YL L 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
37 Limitless Black Uniform 27 XL S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
38 Limitless Black Uniform 23 S S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
39 Limitless Black Uniform 21 S M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
40 Limitless Black Uniform 23 YXL YXL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
41 Limitless Black Uniform 33 YXL YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
42 Limitless Black Uniform 8 S M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
43 Limitless Black Uniform 11 YXL YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
44 Limitless Black Uniform 54 S YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
45 Limitless Black Uniform 7 YXL S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
46 Limitless Black Uniform 9 M YM 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
47 Limitless Black Uniform 5 YM S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
48 Limitless Black Uniform 34 M M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
49 Limitless Black Uniform 10 YM S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
50 Limitless Black Uniform 2 M YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
51 Limitless Black Uniform 17 YL YL 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
52 Limitless Black Uniform 0 L YS 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
53 Limitless Black Uniform 0 YL M 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
54 Limitless Black Uniform 19 YL YM 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
55 Limitless Black Uniform 34 XL S 45.00 1 45 4.5 2019-08-31 22:22:38 20190901-0181 dawaun@limitlessbasketball.com
56 Limitless Reversible Jersey 22 L 25.00 1 25 2.5 2019-08-31 22:27:51 20190901-0181 dawaun@limitlessbasketball.com
57 Limitless Reversible Jersey 40 L 25.00 1 25 2.5 2019-08-31 22:27:51 20190901-0181 dawaun@limitlessbasketball.com
58 Limitless Reversible Jersey 34 L 25.00 1 25 2.5 2019-08-31 22:28:24 20190901-0181 dawaun@limitlessbasketball.com
59 Limitless Reversible Jersey 5 L 25.00 1 25 2.5 2019-08-31 22:28:24 20190901-0181 dawaun@limitlessbasketball.com
60 Limitless Reversible Jersey 1 L 25.00 1 25 2.5 2019-08-31 22:29:26 20190901-0181 dawaun@limitlessbasketball.com
61 Limitless Reversible Jersey 24 L 25.00 1 25 2.5 2019-08-31 22:29:26 20190901-0181 dawaun@limitlessbasketball.com
62 Limitless Reversible Jersey 5 M 25.00 1 25 2.5 2019-08-31 22:33:16 20190901-0181 dawaun@limitlessbasketball.com
63 Limitless Reversible Jersey 0 L 25.00 1 25 2.5 2019-08-31 22:33:16 20190901-0181 dawaun@limitlessbasketball.com
64 Limitless Reversible Jersey 42 M 25.00 1 25 2.5 2019-08-31 22:35:11 20190901-0181 dawaun@limitlessbasketball.com
65 Limitless Reversible Jersey 35 M 25.00 1 25 2.5 2019-08-31 22:35:11 20190901-0181 dawaun@limitlessbasketball.com
66 Limitless Reversible Jersey 21 M 25.00 1 25 2.5 2019-08-31 22:35:44 20190901-0181 dawaun@limitlessbasketball.com
67 Limitless Reversible Jersey 21 M 25.00 1 25 2.5 2019-08-31 22:35:44 20190901-0181 dawaun@limitlessbasketball.com
68 Limitless Reversible Jersey 12 M 25.00 1 25 2.5 2019-08-31 22:36:13 20190901-0181 dawaun@limitlessbasketball.com
69 Limitless Reversible Jersey 9 M 25.00 1 25 2.5 2019-08-31 22:36:13 20190901-0181 dawaun@limitlessbasketball.com
70 Limitless Reversible Jersey 4 M 25.00 1 25 2.5 2019-08-31 22:36:29 20190901-0181 dawaun@limitlessbasketball.com
71 Limitless Reversible Jersey 4 M 25.00 1 25 2.5 2019-08-31 22:36:29 20190901-0181 dawaun@limitlessbasketball.com
72 Limitless Reversible Jersey 10 M 25.00 1 25 2.5 2019-08-31 22:40:17 20190901-0181 dawaun@limitlessbasketball.com
73 Limitless Reversible Jersey 42 M 25.00 1 25 2.5 2019-08-31 22:40:17 20190901-0181 dawaun@limitlessbasketball.com
74 Limitless Reversible Jersey 2 M 25.00 1 25 2.5 2019-08-31 22:40:56 20190901-0181 dawaun@limitlessbasketball.com
75 Limitless Reversible Jersey 23 M 25.00 1 25 2.5 2019-08-31 22:40:56 20190901-0181 dawaun@limitlessbasketball.com
76 Limitless Reversible Jersey 7 M 25.00 1 25 2.5 2019-08-31 22:42:48 20190901-0181 dawaun@limitlessbasketball.com
77 Limitless Reversible Jersey 0 M 25.00 1 25 2.5 2019-08-31 22:42:48 20190901-0181 dawaun@limitlessbasketball.com
78 Limitless Reversible Jersey 7 M 25.00 1 25 2.5 2019-08-31 22:44:29 20190901-0181 dawaun@limitlessbasketball.com
79 Limitless Reversible Jersey 34 M 25.00 1 25 2.5 2019-08-31 22:44:29 20190901-0181 dawaun@limitlessbasketball.com
80 Limitless Reversible Jersey 9 M 25.00 1 25 2.5 2019-08-31 22:45:11 20190901-0181 dawaun@limitlessbasketball.com
81 Limitless Reversible Jersey 8 M 25.00 1 25 2.5 2019-08-31 22:45:11 20190901-0181 dawaun@limitlessbasketball.com
82 Limitless Reversible Jersey 11 M 25.00 1 25 2.5 2019-08-31 22:45:59 20190901-0181 dawaun@limitlessbasketball.com
83 Limitless Reversible Jersey 35 S 25.00 1 25 2.5 2019-08-31 22:45:59 20190901-0181 dawaun@limitlessbasketball.com
84 Limitless Reversible Jersey 33 S 25.00 1 25 2.5 2019-08-31 22:47:01 20190901-0181 dawaun@limitlessbasketball.com
85 Limitless Reversible Jersey 3 S 25.00 1 25 2.5 2019-08-31 22:47:01 20190901-0181 dawaun@limitlessbasketball.com
86 Limitless Reversible Jersey 23 S 25.00 1 25 2.5 2019-08-31 22:47:29 20190901-0181 dawaun@limitlessbasketball.com
87 Limitless Reversible Jersey 8 S 25.00 1 25 2.5 2019-08-31 22:47:29 20190901-0181 dawaun@limitlessbasketball.com
88 Limitless Reversible Jersey 15 S 25.00 1 25 2.5 2019-08-31 22:48:30 20190901-0181 dawaun@limitlessbasketball.com
89 Limitless Reversible Jersey 23 S 25.00 1 25 2.5 2019-08-31 22:48:30 20190901-0181 dawaun@limitlessbasketball.com
90 Limitless Reversible Jersey 20 S 25.00 1 25 2.5 2019-08-31 22:49:02 20190901-0181 dawaun@limitlessbasketball.com
91 Limitless Reversible Jersey 1 S 25.00 1 25 2.5 2019-08-31 22:49:02 20190901-0181 dawaun@limitlessbasketball.com
92 Limitless Reversible Jersey 12 S 25.00 1 25 2.5 2019-08-31 22:49:42 20190901-0181 dawaun@limitlessbasketball.com
93 Limitless Reversible Jersey 31 S 25.00 1 25 2.5 2019-08-31 22:49:42 20190901-0181 dawaun@limitlessbasketball.com
94 Limitless Reversible Jersey 11 S 25.00 1 25 2.5 2019-08-31 22:50:16 20190901-0181 dawaun@limitlessbasketball.com
95 Limitless Reversible Jersey 9 S 25.00 1 25 2.5 2019-08-31 22:50:16 20190901-0181 dawaun@limitlessbasketball.com
96 Limitless Reversible Jersey 5 S 25.00 1 25 2.5 2019-08-31 22:51:24 20190901-0181 dawaun@limitlessbasketball.com
97 Limitless Reversible Jersey 1 S 25.00 1 25 2.5 2019-08-31 22:51:24 20190901-0181 dawaun@limitlessbasketball.com
98 Limitless Reversible Jersey 35 S 25.00 1 25 2.5 2019-08-31 22:51:59 20190901-0181 dawaun@limitlessbasketball.com
99 Limitless Reversible Jersey 1 S 25.00 1 25 2.5 2019-08-31 22:51:59 20190901-0181 dawaun@limitlessbasketball.com
100 Limitless Reversible Jersey 14 S 25.00 1 25 2.5 2019-08-31 22:52:28 20190901-0181 dawaun@limitlessbasketball.com
101 Limitless Reversible Jersey 0 S 25.00 1 25 2.5 2019-08-31 22:52:28 20190901-0181 dawaun@limitlessbasketball.com
102 Limitless Reversible Jersey 12 S 25.00 1 25 2.5 2019-08-31 22:53:20 20190901-0181 dawaun@limitlessbasketball.com
103 Limitless Reversible Jersey 25 S 25.00 1 25 2.5 2019-08-31 22:53:20 20190901-0181 dawaun@limitlessbasketball.com
104 Limitless Reversible Jersey 67 S 25.00 1 25 2.5 2019-08-31 22:56:45 20190901-0181 dawaun@limitlessbasketball.com
105 Limitless Reversible Jersey 54 S 25.00 1 25 2.5 2019-08-31 22:56:45 20190901-0181 dawaun@limitlessbasketball.com
106 Limitless Reversible Jersey 8 S 25.00 1 25 2.5 2019-08-31 22:58:19 20190901-0181 dawaun@limitlessbasketball.com
107 Limitless Reversible Jersey 30 S 25.00 1 25 2.5 2019-08-31 22:58:19 20190901-0181 dawaun@limitlessbasketball.com
108 Limitless Reversible Jersey 34 S 25.00 1 25 2.5 2019-08-31 23:09:10 20190901-0181 dawaun@limitlessbasketball.com
109 Limitless Reversible Jersey 6 S 25.00 1 25 2.5 2019-08-31 23:09:10 20190901-0181 dawaun@limitlessbasketball.com
110 Limitless Reversible Jersey 4 S 25.00 1 25 2.5 2019-08-31 23:09:44 20190901-0181 dawaun@limitlessbasketball.com
111 Limitless Reversible Jersey 21 S 25.00 1 25 2.5 2019-08-31 23:09:44 20190901-0181 dawaun@limitlessbasketball.com
112 Limitless Reversible Jersey 23 S 25.00 1 25 2.5 2019-08-31 23:11:18 20190901-0181 dawaun@limitlessbasketball.com
113 Limitless Reversible Jersey 12 S 25.00 1 25 2.5 2019-08-31 23:11:18 20190901-0181 dawaun@limitlessbasketball.com
114 Limitless Reversible Jersey 0 S 25.00 1 25 2.5 2019-08-31 23:11:57 20190901-0181 dawaun@limitlessbasketball.com
115 Limitless Reversible Jersey 26 XL 25.00 1 25 2.5 2019-08-31 23:11:57 20190901-0181 dawaun@limitlessbasketball.com
116 Limitless Reversible Jersey 34 XL 25.00 1 25 2.5 2019-08-31 23:13:25 20190901-0181 dawaun@limitlessbasketball.com
117 Limitless Reversible Jersey 2 XL 25.00 1 25 2.5 2019-08-31 23:13:25 20190901-0181 dawaun@limitlessbasketball.com
118 Limitless Reversible Jersey 11 XL 25.00 1 25 2.5 2019-08-31 23:13:55 20190901-0181 dawaun@limitlessbasketball.com
119 Limitless Reversible Jersey 20 XL 25.00 1 25 2.5 2019-08-31 23:13:55 20190901-0181 dawaun@limitlessbasketball.com
120 Limitless Reversible Jersey 34 XL 25.00 1 25 2.5 2019-08-31 23:15:34 20190901-0181 dawaun@limitlessbasketball.com
121 Limitless Reversible Jersey 27 XL 25.00 1 25 2.5 2019-08-31 23:15:34 20190901-0181 dawaun@limitlessbasketball.com
122 Limitless Reversible Jersey 15 YL 25.00 1 25 2.5 2019-08-31 23:16:17 20190901-0181 dawaun@limitlessbasketball.com
123 Limitless Reversible Jersey 3 YL 25.00 1 25 2.5 2019-08-31 23:16:17 20190901-0181 dawaun@limitlessbasketball.com
124 Limitless Reversible Jersey 28 YL 25.00 1 25 2.5 2019-08-31 23:16:59 20190901-0181 dawaun@limitlessbasketball.com
125 Limitless Reversible Jersey 0 YL 25.00 1 25 2.5 2019-08-31 23:16:59 20190901-0181 dawaun@limitlessbasketball.com
126 Limitless Reversible Jersey 2 YL 25.00 1 25 2.5 2019-08-31 23:18:38 20190901-0181 dawaun@limitlessbasketball.com
127 Limitless Reversible Jersey 36 YL 25.00 1 25 2.5 2019-08-31 23:18:38 20190901-0181 dawaun@limitlessbasketball.com
128 Limitless Reversible Jersey 13 YL 25.00 1 25 2.5 2019-08-31 23:19:09 20190901-0181 dawaun@limitlessbasketball.com
129 Limitless Reversible Jersey 22 YL 25.00 1 25 2.5 2019-08-31 23:19:09 20190901-0181 dawaun@limitlessbasketball.com
130 Limitless Reversible Jersey 22 YL 25.00 1 25 2.5 2019-08-31 23:20:11 20190901-0181 dawaun@limitlessbasketball.com
131 Limitless Reversible Jersey 10 YL 25.00 1 25 2.5 2019-08-31 23:20:11 20190901-0181 dawaun@limitlessbasketball.com
132 Limitless Reversible Jersey 33 YL 25.00 1 25 2.5 2019-08-31 23:20:57 20190901-0181 dawaun@limitlessbasketball.com
133 Limitless Reversible Jersey 30 YL 25.00 1 25 2.5 2019-08-31 23:20:57 20190901-0181 dawaun@limitlessbasketball.com
134 Limitless Reversible Jersey 30 YL 25.00 1 25 2.5 2019-08-31 23:21:28 20190901-0181 dawaun@limitlessbasketball.com
135 Limitless Reversible Jersey 33 YL 25.00 1 25 2.5 2019-08-31 23:21:28 20190901-0181 dawaun@limitlessbasketball.com
136 Limitless Reversible Jersey 21 YL 25.00 1 25 2.5 2019-08-31 23:22:05 20190901-0181 dawaun@limitlessbasketball.com
137 Limitless Reversible Jersey 30 YL 25.00 1 25 2.5 2019-08-31 23:22:05 20190901-0181 dawaun@limitlessbasketball.com
138 Limitless Reversible Jersey 19 YL 25.00 1 25 2.5 2019-08-31 23:22:43 20190901-0181 dawaun@limitlessbasketball.com
139 Limitless Reversible Jersey 13 YL 25.00 1 25 2.5 2019-08-31 23:22:43 20190901-0181 dawaun@limitlessbasketball.com
140 Limitless Reversible Jersey 2 YL 25.00 1 25 2.5 2019-08-31 23:23:07 20190901-0181 dawaun@limitlessbasketball.com
141 Limitless Reversible Jersey 7 YL 25.00 1 25 2.5 2019-08-31 23:23:07 20190901-0181 dawaun@limitlessbasketball.com
142 Limitless Reversible Jersey 21 YL 25.00 1 25 2.5 2019-08-31 23:24:00 20190901-0181 dawaun@limitlessbasketball.com
143 Limitless Reversible Jersey 0 YL 25.00 1 25 2.5 2019-08-31 23:24:00 20190901-0181 dawaun@limitlessbasketball.com
144 Limitless Reversible Jersey 17 YL 25.00 1 25 2.5 2019-08-31 23:24:33 20190901-0181 dawaun@limitlessbasketball.com
145 Limitless Reversible Jersey 17 YL 25.00 1 25 2.5 2019-08-31 23:24:33 20190901-0181 dawaun@limitlessbasketball.com
146 Limitless Reversible Jersey 53 YL 25.00 1 25 2.5 2019-08-31 23:25:07 20190901-0181 dawaun@limitlessbasketball.com
147 Limitless Reversible Jersey 6 YL 25.00 1 25 2.5 2019-08-31 23:25:07 20190901-0181 dawaun@limitlessbasketball.com
148 Limitless Reversible Jersey 5 YM 25.00 1 25 2.5 2019-08-31 23:25:33 20190901-0181 dawaun@limitlessbasketball.com
149 Limitless Reversible Jersey 3 YM 25.00 1 25 2.5 2019-08-31 23:25:33 20190901-0181 dawaun@limitlessbasketball.com
150 Limitless Reversible Jersey 33 YM 25.00 1 25 2.5 2019-08-31 23:26:05 20190901-0181 dawaun@limitlessbasketball.com
151 Limitless Reversible Jersey 23 YM 25.00 1 25 2.5 2019-08-31 23:26:05 20190901-0181 dawaun@limitlessbasketball.com
152 Limitless Reversible Jersey 8 YM 25.00 1 25 2.5 2019-08-31 23:26:49 20190901-0181 dawaun@limitlessbasketball.com
153 Limitless Reversible Jersey 34 YM 25.00 1 25 2.5 2019-08-31 23:26:49 20190901-0181 dawaun@limitlessbasketball.com
154 Limitless Reversible Jersey 23 YM 25.00 1 25 2.5 2019-08-31 23:27:19 20190901-0181 dawaun@limitlessbasketball.com
155 Limitless Reversible Jersey 2 YM 25.00 1 25 2.5 2019-08-31 23:27:19 20190901-0181 dawaun@limitlessbasketball.com
156 Limitless Reversible Jersey 10 YM 25.00 1 25 2.5 2019-08-31 23:27:51 20190901-0181 dawaun@limitlessbasketball.com
157 Limitless Reversible Jersey 28 YM 25.00 1 25 2.5 2019-08-31 23:27:51 20190901-0181 dawaun@limitlessbasketball.com
158 Limitless Reversible Jersey 18 YM 25.00 1 25 2.5 2019-08-31 23:29:05 20190901-0181 dawaun@limitlessbasketball.com
159 Limitless Reversible Jersey 23 YM 25.00 1 25 2.5 2019-08-31 23:29:05 20190901-0181 dawaun@limitlessbasketball.com
160 Limitless Reversible Jersey 5 YM 25.00 1 25 2.5 2019-08-31 23:29:36 20190901-0181 dawaun@limitlessbasketball.com
161 Limitless Reversible Jersey 29 YS 25.00 1 25 2.5 2019-08-31 23:31:02 20190901-0181 dawaun@limitlessbasketball.com
162 Limitless Reversible Jersey 5 YS 25.00 1 25 2.5 2019-08-31 23:31:19 20190901-0181 dawaun@limitlessbasketball.com
163 Limitless Reversible Jersey 1 YS 25.00 1 25 2.5 2019-08-31 23:31:47 20190901-0181 dawaun@limitlessbasketball.com
164 Limitless Reversible Jersey 21 YXL 25.00 1 25 2.5 2019-08-31 23:32:15 20190901-0181 dawaun@limitlessbasketball.com
165 Limitless Reversible Jersey 33 YXL 25.00 1 25 2.5 2019-08-31 23:32:15 20190901-0181 dawaun@limitlessbasketball.com
166 Limitless Reversible Jersey 11 YXL 25.00 1 25 2.5 2019-08-31 23:32:45 20190901-0181 dawaun@limitlessbasketball.com
167 Limitless Reversible Jersey 10 YXL 25.00 1 25 2.5 2019-08-31 23:32:45 20190901-0181 dawaun@limitlessbasketball.com
168 Limitless Reversible Jersey 9 YXL 25.00 1 25 2.5 2019-08-31 23:33:24 20190901-0181 dawaun@limitlessbasketball.com
169 Limitless Reversible Jersey 20 YXL 25.00 1 25 2.5 2019-08-31 23:33:24 20190901-0181 dawaun@limitlessbasketball.com
170 Limitless Reversible Jersey 3 YXL 25.00 1 25 2.5 2019-08-31 23:34:02 20190901-0181 dawaun@limitlessbasketball.com
171 Limitless Reversible Jersey 7 YXL 25.00 1 25 2.5 2019-08-31 23:34:02 20190901-0181 dawaun@limitlessbasketball.com
172 Limitless Reversible Jersey 15 YXL 25.00 1 25 2.5 2019-08-31 23:34:28 20190901-0181 dawaun@limitlessbasketball.com
173 Limitless Reversible Jersey 11 YXL 25.00 1 25 2.5 2019-08-31 23:34:28 20190901-0181 dawaun@limitlessbasketball.com
174 Limitless Reversible Jersey 30 YXL 25.00 1 25 2.5 2019-08-31 23:34:55 20190901-0181 dawaun@limitlessbasketball.com
175 Limitless Reversible Jersey 10 YXL 25.00 1 25 2.5 2019-08-31 23:34:55 20190901-0181 dawaun@limitlessbasketball.com
176 Limitless Reversible Jersey 0 YXL 25.00 1 25 2.5 2019-08-31 23:35:27 20190901-0181 dawaun@limitlessbasketball.com
177 Limitless Reversible Jersey 33 YXL 25.00 1 25 2.5 2019-08-31 23:35:27 20190901-0181 dawaun@limitlessbasketball.com
178 Limitless Reversible Jersey 11 YXL 25.00 1 25 2.5 2019-08-31 23:35:56 20190901-0181 dawaun@limitlessbasketball.com
179 Limitless Reversible Jersey 23 YXL 25.00 1 25 2.5 2019-08-31 23:35:56 20190901-0181 dawaun@limitlessbasketball.com
180 Limitless Reversible Jersey 21 YXL 25.00 1 25 2.5 2019-08-31 23:36:11 20190901-0181 dawaun@limitlessbasketball.com

View File

@@ -1,4 +0,0 @@
StoreName,ProductName,NAME,NUMBER,Size,JerseySize,ShortsSize,Price,Quantity,TotalPrice,Tax,DateCreated,InvoiceNumber,Payer_Email
"Bruton Basketball","Long Sleeve T Shirt",,,2XL,,,45.00,1,45,4.5,"2019-09-01 17:38:41",20190901-0182,clare.davis@fire.tas.gov.au
"Bruton Basketball","T Shirt",,,2XL,,,35.00,1,35,3.5,"2019-09-01 17:39:01",20190901-0182,clare.davis@fire.tas.gov.au
"Bruton Basketball","Long Sleeve Hoodie",,,3XL,,,50.00,1,50,5,"2019-09-01 17:39:19",20190901-0182,clare.davis@fire.tas.gov.au
1 StoreName ProductName NAME NUMBER Size JerseySize ShortsSize Price Quantity TotalPrice Tax DateCreated InvoiceNumber Payer_Email
2 Bruton Basketball Long Sleeve T Shirt 2XL 45.00 1 45 4.5 2019-09-01 17:38:41 20190901-0182 clare.davis@fire.tas.gov.au
3 Bruton Basketball T Shirt 2XL 35.00 1 35 3.5 2019-09-01 17:39:01 20190901-0182 clare.davis@fire.tas.gov.au
4 Bruton Basketball Long Sleeve Hoodie 3XL 50.00 1 50 5 2019-09-01 17:39:19 20190901-0182 clare.davis@fire.tas.gov.au

View File

@@ -1,7 +0,0 @@
StoreName,ProductName,NAME,NUMBER,Size,JerseySize,ShortsSize,Price,Quantity,TotalPrice,Tax,DateCreated,InvoiceNumber,Payer_Email
Ice,"Practice Jersey Reversible",SIMON,55,YM,,,30.00,1,30,3,"2019-10-26 09:17:16",20191026-0275,simondj55@gmail.com
"San Diego Bulldogs","Long Sleeve Hoodie",,,YXL,,,45.00,1,45,4.5,"2019-10-26 17:50:31",20191026-0276,sjones023@att.net
"San Diego Bulldogs",Backpack,"MJ ",23,,,,70.00,1,70,7,"2019-10-26 17:51:14",20191026-0276,sjones023@att.net
Wauconda,"Game Day Reversible uniform",PIEHL,12,,L,L,65.00,1,65,6.5,"2019-10-26 18:12:46",20191026-0277,aprilo99@aol.com
Wauconda,"Dry fit Long Sleeve T Shirt",,,L,,,30.00,1,30,3,"2019-10-26 18:21:16",20191026-0277,aprilo99@aol.com
Wauconda,socks,,,,,,12.00,1,12,1.2000000000000002,"2019-10-26 18:21:33",20191026-0277,aprilo99@aol.com
1 StoreName ProductName NAME NUMBER Size JerseySize ShortsSize Price Quantity TotalPrice Tax DateCreated InvoiceNumber Payer_Email
2 Ice Practice Jersey Reversible SIMON 55 YM 30.00 1 30 3 2019-10-26 09:17:16 20191026-0275 simondj55@gmail.com
3 San Diego Bulldogs Long Sleeve Hoodie YXL 45.00 1 45 4.5 2019-10-26 17:50:31 20191026-0276 sjones023@att.net
4 San Diego Bulldogs Backpack MJ 23 70.00 1 70 7 2019-10-26 17:51:14 20191026-0276 sjones023@att.net
5 Wauconda Game Day Reversible uniform PIEHL 12 L L 65.00 1 65 6.5 2019-10-26 18:12:46 20191026-0277 aprilo99@aol.com
6 Wauconda Dry fit Long Sleeve T Shirt L 30.00 1 30 3 2019-10-26 18:21:16 20191026-0277 aprilo99@aol.com
7 Wauconda socks 12.00 1 12 1.2000000000000002 2019-10-26 18:21:33 20191026-0277 aprilo99@aol.com

View File

@@ -48,630 +48,254 @@ $array_orders = getSubItem($dateToday);
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Order Details</title>
<style>
img {
border: none;
-ms-interpolation-mode: bicubic;
max-width: 100%;
}
body {
background-color: #f6f6f6;
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 12px;
line-height: 1.4;
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
width: 100%;
}
table {
border-collapse: separate;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
width: 100%;
}
table td {
font-family: sans-serif;
font-size: 10px;
vertical-align: top;
}
/* -------------------------------------
BODY & CONTAINER
------------------------------------- */
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
.container {
display: block;
margin: 0 auto !important;
/* makes it centered */
max-width: 880px;
padding: 10px;
width: 880px;
}
/* This should also be a block element, so that it will fill 100% of the .container */
.content {
box-sizing: border-box;
display: block;
margin: 0 auto;
max-width: 880px;
padding: 10px;
}
/* -------------------------------------
HEADER, FOOTER, MAIN
------------------------------------- */
.main {
background: #ffffff;
border-radius: 3px;
width: 100%;
}
.wrapper {
box-sizing: border-box;
padding: 20px;
}
.content-block {
padding-bottom: 10px;
padding-top: 10px;
}
.footer {
clear: both;
margin-top: 10px;
text-align: center;
width: 100%;
}
.footer td,
.footer p,
.footer span,
.footer a {
color: #999999;
font-size: 12px;
text-align: center;
}
/* -------------------------------------
TYPOGRAPHY
------------------------------------- */
h1,
h2,
h3,
h4 {
color: #000000;
font-family: sans-serif;
font-weight: 400;
line-height: 1.4;
margin: 0;
margin-bottom: 20px;
}
h1 {
font-size: 35px;
font-weight: 300;
text-align: center;
text-transform: capitalize;
}
p,
ul,
ol {
font-family: sans-serif;
font-size: 14px;
font-weight: normal;
margin: 0;
margin-bottom: 15px;
}
p li,
ul li,
ol li {
list-style-position: inside;
margin-left: 5px;
}
a {
color: #3498db;
text-decoration: underline;
}
/* -------------------------------------
BUTTONS
------------------------------------- */
.btn {
box-sizing: border-box;
width: 100%;
}
.btn>tbody>tr>td {
padding-bottom: 15px;
}
.btn table {
width: auto;
}
.btn table td {
background-color: #ffffff;
border-radius: 5px;
text-align: center;
}
.btn a {
background-color: #ffffff;
border: solid 1px #3498db;
border-radius: 5px;
box-sizing: border-box;
color: #3498db;
cursor: pointer;
display: inline-block;
font-size: 14px;
font-weight: bold;
margin: 0;
padding: 12px 25px;
text-decoration: none;
text-transform: capitalize;
}
.btn-primary table td {
background-color: #3498db;
}
.btn-primary a {
background-color: #3498db;
border-color: #3498db;
color: #ffffff;
}
/* -------------------------------------
OTHER STYLES THAT MIGHT BE USEFUL
------------------------------------- */
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.clear {
clear: both;
}
.mt0 {
margin-top: 0;
}
.mb0 {
margin-bottom: 0;
}
.preheader {
color: transparent;
display: none;
height: 0;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
mso-hide: all;
visibility: hidden;
width: 0;
}
.powered-by a {
text-decoration: none;
}
hr {
border: 0;
border-bottom: 1px solid #f6f6f6;
margin: 20px 0;
}
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 12px !important;
}
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .btn table {
width: 100% !important;
}
table[class=body] .btn a {
width: 100% !important;
}
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
.btn-primary table td:hover {
background-color: #34495e !important;
}
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important;
}
}
.table-bordered td,
th {
border: 1px solid black;
padding: 2px;
}
.previewImage {
height: 200px;
overflow: hidden;
object-fit: contain;
}
@media print {
.items tr {
page-break-inside: avoid;
position: relative;
}
}
@page {
size: 18cm 26.7cm;
margin: 1cm;
}
#tbl_subitem tr td {
text-align: center;
}
</style>
<link rel="stylesheet" href="styles.css">
</head>
<body class="" onload="window.print()">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
<tr>
<td>&nbsp;</td>
<td class="container">
<div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<table role="presentation" class="main">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<h3 class="align-center" style="font-size: 15px;"><b>Daily Reports
<?php echo $dateToday ?></b> </h3>
<br>
<?php
$q = $conn->prepare("SELECT t.StoreName, o.ProductId, o.FormUsed, o.ProductName, o.NAME, o.NUMBER, o.Size, o.JerseySize, o.ShortsSize, o.Price, o.Quantity, (o.Price * o.Quantity) AS TotalPrice, ((o.Price * o.Quantity) * 0.10) AS Tax,
o.DateCreated, pd.InvoiceNumber, pd.Payer_Email FROM orders AS o
INNER JOIN payment_details AS pd ON pd.CartKey = o.CartKey
INNER JOIN teamstores AS t ON t.Id = o.StoreId
WHERE o.DateCreated BETWEEN '$dateToday 00:00:00' AND '$dateToday 23:59:00'
GROUP BY o.ProductId
ORDER BY o.DateCreated");
$q->execute();
$result = $q->rowCount();
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
<tr>
<td>&nbsp;</td>
<td class="container">
<div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<table role="presentation" class="main">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<h3 class="align-center" style="font-size: 15px;"><b>Daily Reports <?php echo $dateToday ?></b></h3>
<br>
<?php
$q = $conn->prepare("SELECT t.StoreName, o.ProductId, o.FormUsed, o.ProductName, o.NAME, o.NUMBER, o.Size, o.JerseySize, o.ShortsSize, o.Price, o.Quantity, (o.Price * o.Quantity) AS TotalPrice, ((o.Price * o.Quantity) * 0.10) AS Tax,
o.DateCreated, pd.InvoiceNumber, pd.Payer_Email FROM orders AS o
INNER JOIN payment_details AS pd ON pd.CartKey = o.CartKey
INNER JOIN teamstores AS t ON t.Id = o.StoreId
WHERE o.DateCreated BETWEEN '$dateToday 00:00:00' AND '$dateToday 23:59:00'
GROUP BY o.ProductId
ORDER BY o.DateCreated");
$q->execute();
$result = $q->rowCount();
if($result > 0){
// $i = 1;
while ($row = $q->fetch()) {
if($result > 0){
while ($row = $q->fetch()) {
?>
<div class="items-parent" style="border: 1px solid #e2e2e2; padding: 10px; margin-bottom: 10px;">
<table class="items" role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<h2><b>Store: </b></h2>
</td>
<td>
<h2><?php echo $row['StoreName'] ?></h2>
</td>
</tr>
<tr>
<td colspan="2">
<div style="font-size: 12px;">
<a href="#"><?php echo $row['ProductName'] ?></a>
</div>
<div style="text-align: center;">
<?php
$itemImages = getItemImages($row['ProductId']);
foreach($itemImages as $thumb_key => $thumb_val){
echo '<img style="height: 150px; overflow: hidden; object-fit: contain;" src="https://crewsportswear.app:5955/'.$thumb_val['Image'].'"> ';
}
?>
</div>
<table id="tbl_subitem"class="table table-condensed table-bordered" style="width: 100%; border-collapse: collapse;">
<?php if($row['FormUsed']=="jersey-and-shorts-form"){ ?>
<tr>
<td><b>#</b></td>
<td><b>Name</b></td>
<td><b>Number</b></td>
<td><b>Jersey Size</b></td>
<td><b>Shorts Size</b></td>
<td><b>Quantity</b></td>
</tr>
<?php }elseif($row['FormUsed']=="tshirt-form"){ ?>
<tr>
<td><b>#</b></td>
<td><b>Size</b></td>
<td><b>Quantity</b></td>
</tr>
<?php }elseif($row['FormUsed']=="quantity-form"){ ?>
<tr>
<td><b>#</b></td>
<td>Quantity</b></td>
</tr>
<?php }elseif($row['FormUsed']=="name-number-form"){ ?>
<tr>
<td><b>#</b></td>
<td><b>Name</b></td>
<td><b>Number</b></td>
<td><b>Quantity</b></td>
</tr>
<?php }elseif($row['FormUsed']=="name-number-size-form"){ ?>
<tr>
<td><b>#</b></td>
<th>Name</th>
<th>Number</th>
<th>Size</th>
<th>Quantity</th>
</tr>
<?php }elseif($row['FormUsed']=="number-form"){ ?>
<tr>
<td><b>#</b></td>
<th>Number</th>
<th>Quantity</th>
</tr>
<?php }elseif($row['FormUsed']=="name-name2-size-form"){ ?>
<tr>
<td><b>#</b></td>
<td>Gamer Tag</td>
<td>Name</td>
<td>Size</td>
<td>Quantity</td>
</tr>
<?php }elseif($row['FormUsed']=="name-size-form"){ ?>
<tr>
<td><b>#</b></td>
<th>Name</th>
<th>Size</th>
<th>Quantity</th>
</tr>
<?php }elseif($row['FormUsed']=="jersey-and-shorts-quantity-form"){ ?>
<tr>
<td><b>#</b></td>
<th>Jersey Size</th>
<th>Shorts Size</th>
<th>Quantity</th>
</tr>
<?php }elseif($row['FormUsed']=="number-jersey-shorts-form"){ ?>
<tr>
<td><b>#</b></td>
<td><b>Number</b></td>
<td><b>Jersey Size</b></td>
<td><b>Shorts Size</b></td>
<td><b>Quantity</b></td>
</tr>
<?php }else{ /* else */ }
?>
<div class="items-parent"
style="border: 1px solid #e2e2e2; padding: 10px; margin-bottom: 10px;">
$i=1;
<table class="items" role="presentation" border="0" cellpadding="0"
cellspacing="0">
<tbody>
<tr>
<td>
<h2><b>Store: </b></h2>
</td>
<td>
<h2><?php echo $row['StoreName'] ?></h2>
</td>
</tr>
<tr>
<td colspan="2">
<div style="font-size: 12px;">
<a href="#">
<?php echo $row['ProductName'] ?>
</a>
</div>
<div style="text-align: center;">
<!-- -->
<?php
$itemImages = getItemImages($row['ProductId']);
foreach($itemImages as $thumb_key => $thumb_val){
// echo $thumb_val['Image'];
echo '<img style="height: 150px; overflow: hidden; object-fit: contain;" src="https://crewsportswear.app/images/'.$thumb_val['Image'].'"> ';
}
?>
</div>
<table id="tbl_subitem"
class="table table-condensed table-bordered"
style="width: 100%; border-collapse: collapse;">
<?php
foreach($array_orders as $key => $val){
if($val['ProductId'] == $row['ProductId']){
if($row['FormUsed']=="jersey-and-shorts-form"){ ?>
<tr>
<td><?php echo $i++ ?></td>
<td><?php echo ($val['Name'] !== "") ? : '--' ?></td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['JerseySize'] ?> </td>
<td><?php echo $val['ShortsSize'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="tshirt-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Size'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="quantity-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="name-number-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Name'] ?> </td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="name-number-size-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Name'] ?> </td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['Size'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="number-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="name-name2-size-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Name'] ?> </td>
<td><?php echo $val['Name2'] ?> </td>
<td><?php echo $val['Size'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="name-size-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Name'] ?> </td>
<td><?php echo $val['Size'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="jersey-and-shorts-quantity-form"){ ?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['JerseySize'] ?> </td>
<td><?php echo $val['ShortsSize'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }elseif($row['FormUsed']=="number-jersey-shorts-form"){ ?>
<tr>
<td><?php echo $i++ ?></td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['JerseySize'] ?> </td>
<td><?php echo $val['ShortsSize'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php }else{ /* else */ }
}
} ?>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<?php
}
}
?>
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- END CENTERED WHITE CONTAINER -->
if($row['FormUsed']=="jersey-and-shorts-form"){
?>
<tr>
<td><b>#</b></td>
<td><b>Name</b></td>
<td><b>Number</b></td>
<td><b>Jersey Size</b></td>
<td><b>Shorts Size</b></td>
<td><b>Quantity</b></td>
</tr>
<?php
}elseif($row['FormUsed']=="tshirt-form"){
?>
<tr>
<td><b>#</b></td>
<td><b>Size</b></td>
<td><b>Quantity</b></td>
</tr>
<?php
}elseif($row['FormUsed']=="quantity-form"){
?>
<tr>
<td>Quantity</b></td>
</tr>
<?php
}elseif($row['FormUsed']=="name-number-form"){
?>
<tr>
<td><b>#</b></td>
<td><b>Name</b></td>
<td><b>Number</b></td>
<td><b>Quantity</b></td>
</tr>
<?php
}elseif($row['FormUsed']=="name-number-size-form"){
?>
<tr>
<td><b>#</b></td>
<th>Name</th>
<th>Number</th>
<th>Size</th>
<th>Quantity</th>
</tr>
<?php
}elseif($row['FormUsed']=="number-form"){
?>
<tr>
<td><b>#</b></td>
<th>Number</th>
<th>Quantity</th>
</tr>
<?php
}elseif($row['FormUsed']=="name-size-form"){
?>
<tr>
<td><b>#</b></td>
<th>Name</th>
<th>Size</th>
<th>Price</th>
<th>Quantity</th>
</tr>
<?php
}else{
// else
}
$i=1;
foreach($array_orders as $key => $val){
if($val['ProductId'] == $row['ProductId']){
if($row['FormUsed']=="jersey-and-shorts-form"){
?>
<tr>
<td>
<?php echo $i++ ?>
</td>
<td>
<?php echo ($val['Name'] !== "") ? : '--' ?>
</td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['JerseySize'] ?> </td>
<td><?php echo $val['ShortsSize'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php
}elseif($row['FormUsed']=="tshirt-form"){
?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Size'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php
}elseif($row['FormUsed']=="quantity-form"){
?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php
}elseif($row['FormUsed']=="name-number-form"){
?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Name'] ?> </td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php
}elseif($row['FormUsed']=="name-number-size-form"){
?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Name'] ?> </td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['Size'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php
}elseif($row['FormUsed']=="number-form"){
?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Number'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php
}elseif($row['FormUsed']=="name-size-form"){
?>
<tr>
<td><?php echo $i++ ?> </td>
<td><?php echo $val['Name'] ?> </td>
<td><?php echo $val['Size'] ?> </td>
<td><?php echo $val['Quantity'] ?> </td>
</tr>
<?php
}else{
}
}
}
?>
<!-- table header -->
<!-- table body -->
</table>
</td>
</tr>
</tbody>
</table>
</div>
<?php
}
}
?>
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- END CENTERED WHITE CONTAINER -->
<!-- START FOOTER -->
<div class="footer">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
<span class="apple-link">Copyright &copy 2019 <a
href="https://crewsportswear.com">crewsportswear.com</a>. All rights
reserved.</span>
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
</div>
</td>
<td>&nbsp;</td>
</tr>
</table>
<!-- START FOOTER -->
<div class="footer">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
<span class="apple-link">Copyright &copy 2019 <a
href="https://crewsportswear.com">crewsportswear.com</a>. All rights
reserved.</span>
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
</div>
</td>
<td>&nbsp;</td>
</tr>
</table>
</body>
</html>

View File

@@ -1,18 +1,18 @@
<?php
$host = "localhost";
$username = "root";
$password = "";
$db = "custom_design";
// Use environment variables for Docker deployment
$host = getenv('DB_HOST') ?: 'localhost';
$username = getenv('DB_USER') ?: 'root';
$password = getenv('DB_PASS') ?: '';
$db = getenv('DB_NAME') ?: 'custom_designs';
$port = getenv('DB_PORT') ?: '3306';
try{
// database connection
$conn = new PDO("mysql:host=$host;dbname=$db",$username,$password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn = new PDO("mysql:host=$host;port=$port;dbname=$db", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $pe)
{
die('Connection error, because: ' .$pe->getMessage());
}
$baseURL = 'http://'.$_SERVER['HTTP_HOST'] . '/bulacanlibrary/';

46
docker-compose.yml Normal file
View File

@@ -0,0 +1,46 @@
version: '3.8'
services:
email-reports:
build: .
container_name: email_reports_unified
restart: unless-stopped
environment:
- TZ=America/Chicago
# Crew Sportswear Database
- DB_HOST_CREW=${DB_HOST_CREW:-mysql}
- DB_PORT_CREW=${DB_PORT_CREW:-3306}
- DB_NAME_CREW=${DB_NAME_CREW:-custom_design}
- DB_USER_CREW=${DB_USER_CREW:-crew_user}
- DB_PASS_CREW=${DB_PASS_CREW}
# MerchBay Database
- DB_HOST_MERCHBAY=${DB_HOST_MERCHBAY:-mysql}
- DB_PORT_MERCHBAY=${DB_PORT_MERCHBAY:-3306}
- DB_NAME_MERCHBAY=${DB_NAME_MERCHBAY:-merchbay_laravel}
- DB_USER_MERCHBAY=${DB_USER_MERCHBAY:-merchbay_user}
- DB_PASS_MERCHBAY=${DB_PASS_MERCHBAY}
# SMTP Configuration (shared)
- SMTP_HOST=${SMTP_HOST:-smtp.gmail.com}
- SMTP_PORT=${SMTP_PORT:-587}
# Crew SMTP
- SMTP_PASS_CREW=${SMTP_PASS_CREW}
# MerchBay SMTP
- SMTP_PASS_MERCHBAY=${SMTP_PASS_MERCHBAY}
volumes:
- ./daily_order_reports_crew:/app/daily_order_reports_crew
- ./daily_order_reports_merchbay:/app/daily_order_reports_merchbay
- ./email.log:/app/email.log
networks:
- crew-app-net
labels:
- "description=Unified Email Reports for Crew & MerchBay"
networks:
crew-app-net:
external: true

2291
email.log

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@ include 'dbconfig.php';
require("phpmailer/class.phpmailer.php");
date_default_timezone_set('America/Chicago');
$dateToday = date('Y-m-d');
//$dateToday = "2019-12-12";
$dateTimeToday = date("Y-m-d H:i:s");
//grab all rows from the table where state is "new" and put into array
@@ -40,7 +41,7 @@ if($result > 0){
}
$report_link = "https://www.crewsportswear.com/email_reports/daily_reports_with_image.php?d=". $dateToday;
$report_link = (getenv('APP_URL') ?: 'https://www.crewsportswear.com') . "/email_reports/daily_reports_with_image.php?d=". $dateToday;
$body = "<html>";
$body .= "<body>";
$body .= "<p> Please download the attached file for today's order report.</p>";
@@ -51,7 +52,8 @@ if($result > 0){
foreach($invoice_array as $invoice){
$v = explode("|", $invoice);
$body .= "<div>Invoice Number: <a href='http://admin.crewsportswear.com:23000/admin/orders/view/" . $v['0']."/print'>" . $v['1'] . "</a></div>";
$admin_url = getenv('ADMIN_URL') ?: 'https://admin.crewsportswear.app';
$body .= "<div>Invoice Number: <a href='" . $admin_url . "/admin/orders/view/" . $v['0']."/print'>" . $v['1'] . "</a></div>";
}
$body .= "</body>";
@@ -63,18 +65,23 @@ if($result > 0){
// $mail->SMTPDebug = 3; // uncomment for debug mode.
$mail->SMTPSecure = 'tls';
$mail->Host = "smtp.gmail.com";
$mail->Port = "587";
$mail->Host = getenv('SMTP_HOST') ?: 'smtp.gmail.com';
$mail->Port = getenv('SMTP_PORT') ?: '587';
//gmail account
$mail->Username = 'no-reply@crewsportswear.com';
$mail->Password = '20HustleHard19!';
//gmail account credentials from environment
$mail->Username = getenv('SMTP_USER') ?: 'mail@crewsportswear.com';
$mail->Password = getenv('SMTP_PASS') ?: 'tjpwykpttvkjilxh';
$mail->SetFrom('orders@crewsportswear.com', 'CREW Daily Order Report');
$mail->addAddress('graphics@crewsportswear.com');
$mail->addBCC("webmaster@crewsportswear.com");
$mail->addBCC("angelo@crewsportswear.com");
// Recipients from environment or defaults
$email_to = getenv('EMAIL_TO') ?: 'graphics@crewsportswear.com';
$mail->addAddress($email_to);
$email_bcc = getenv('EMAIL_BCC') ?: 'webmaster@crewsportswear.com,angelo@crewsportswear.com,production@crewsportswear.com';
foreach (explode(',', $email_bcc) as $bcc_email) {
$mail->addBCC(trim($bcc_email));
}
$mail->addAttachment('daily_order_reports/'.$filename);

154
send_report.php Normal file
View File

@@ -0,0 +1,154 @@
<?php
include 'dbconfig.php';
require("phpmailer/class.phpmailer.php");
date_default_timezone_set('America/Chicago');
$dateToday = date('Y-m-d');
$dateTimeToday = date("Y-m-d H:i:s");
// Determine which brand to process
$brand = getenv('BRAND') ?: 'crew'; // 'crew' or 'merchbay'
// Brand-specific configuration
$config = [
'crew' => [
'db_name' => getenv('DB_NAME_CREW') ?: 'custom_design',
'db_host' => getenv('DB_HOST_CREW') ?: getenv('DB_HOST') ?: 'mysql',
'db_user' => getenv('DB_USER_CREW') ?: 'crew_user',
'db_pass' => getenv('DB_PASS_CREW') ?: getenv('DB_PASS'),
'smtp_user' => 'mail@crewsportswear.com',
'smtp_pass' => getenv('SMTP_PASS_CREW') ?: getenv('SMTP_PASS'),
'email_from' => 'orders@crewsportswear.com',
'email_from_name' => 'CREW Daily Order Report',
'email_to' => 'graphics@crewsportswear.com',
'email_bcc' => ['webmaster@crewsportswear.com', 'angelo@crewsportswear.com', 'production@crewsportswear.com'],
'report_url' => 'https://www.crewsportswear.com/email_reports/daily_reports_with_image.php',
'admin_url' => 'https://admin.crewsportswear.app',
'csv_dir' => 'daily_order_reports_crew',
'log_prefix' => '[CREW]'
],
'merchbay' => [
'db_name' => getenv('DB_NAME_MERCHBAY') ?: 'merchbay_laravel',
'db_host' => getenv('DB_HOST_MERCHBAY') ?: getenv('DB_HOST') ?: 'mysql',
'db_user' => getenv('DB_USER_MERCHBAY') ?: 'merchbay_user',
'db_pass' => getenv('DB_PASS_MERCHBAY') ?: getenv('DB_PASS'),
'smtp_user' => 'support@merchbay.com',
'smtp_pass' => getenv('SMTP_PASS_MERCHBAY') ?: getenv('SMTP_PASS'),
'email_from' => 'orders@merchbay.com',
'email_from_name' => 'Merchbay Daily Order Report',
'email_to' => 'graphics@crewsportswear.com',
'email_bcc' => ['webmaster@crewsportswear.com', 'production@crewsportswear.com'],
'report_url' => 'https://www.crewsportswear.com/email_reports_merchbay/daily_reports_with_image.php',
'admin_url' => 'https://merchbay.app',
'csv_dir' => 'daily_order_reports_merchbay',
'log_prefix' => '[MERCHBAY]'
]
];
$cfg = $config[$brand];
// Connect to brand-specific database
try {
$conn = new PDO(
"mysql:host={$cfg['db_host']};dbname={$cfg['db_name']}",
$cfg['db_user'],
$cfg['db_pass']
);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $pe) {
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']} Database error: " . $pe->getMessage() . "\n";
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
die('Connection error, because: ' .$pe->getMessage());
}
// Query orders
$q = $conn->prepare("SELECT t.StoreName, o.CartKey, o.ProductName, o.NAME, o.NUMBER, o.Size, o.JerseySize, o.ShortsSize, o.Price, o.Quantity, (o.Price * o.Quantity) AS TotalPrice, ((o.Price * o.Quantity) * 0.10) AS Tax,
o.DateCreated, pd.InvoiceNumber, pd.Payer_Email FROM orders AS o
INNER JOIN payment_details AS pd ON pd.CartKey = o.CartKey
INNER JOIN teamstores AS t ON t.Id = o.StoreId
WHERE o.DateCreated BETWEEN '$dateToday 00:00:00' AND '$dateToday 23:59:00'
ORDER BY o.DateCreated");
$q->execute();
$result = $q->rowCount();
if($result > 0){
$invoice_array = array();
// Create CSV directory if it doesn't exist
if (!file_exists($cfg['csv_dir'])) {
mkdir($cfg['csv_dir'], 0755, true);
}
$filename = $cfg['csv_dir'] . '/daily_order_report_'.$dateToday.'.csv';
$headers = array('StoreName', 'ProductName', 'NAME', 'NUMBER', 'Size', 'JerseySize', 'ShortsSize', 'Price', 'Quantity', 'TotalPrice', 'Tax', 'DateCreated', 'InvoiceNumber', 'Payer_Email');
$fp = fopen($filename, 'w');
fputcsv($fp, $headers);
while ($row = $q->fetch()) {
$value = $row['CartKey'] . "|" . $row['InvoiceNumber'];
if(!in_array($value, $invoice_array, true)){
array_push($invoice_array, $value);
}
$lineData = array($row['StoreName'], $row['ProductName'], $row['NAME'], $row['NUMBER'], $row['Size'], $row['JerseySize'], $row['ShortsSize'], $row['Price'], $row['Quantity'], $row['TotalPrice'], $row['Tax'], $row['DateCreated'], $row['InvoiceNumber'], $row['Payer_Email']);
fputcsv($fp, $lineData);
}
fclose($fp);
// Build email body
$report_link = $cfg['report_url'] . "?d=" . $dateToday;
$body = "<html>";
$body .= "<body>";
$body .= "<p>Please download the attached file for today's order report.</p>";
$body .= "<br><br>";
$body .= "<p>For the order report with image please <a href='".$report_link."'>click here</a>.</p>";
$body .= "<p>####################################</p>";
$body .= "<p>Order Details per Invoice</p>";
foreach($invoice_array as $invoice){
$v = explode("|", $invoice);
$body .= "<div>Invoice Number: <a href='" . $cfg['admin_url'] . "/admin/orders/view/" . $v['0'] . "/print'>" . $v['1'] . "</a></div>";
}
$body .= "</body>";
$body .= "</html>";
// Send email
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true;
// $mail->SMTPDebug = 3; // uncomment for debug mode.
$mail->SMTPSecure = 'tls';
$mail->Host = getenv('SMTP_HOST') ?: 'smtp.gmail.com';
$mail->Port = getenv('SMTP_PORT') ?: '587';
$mail->Username = $cfg['smtp_user'];
$mail->Password = $cfg['smtp_pass'];
$mail->SetFrom($cfg['email_from'], $cfg['email_from_name']);
$mail->addAddress($cfg['email_to']);
foreach ($cfg['email_bcc'] as $bcc) {
$mail->addBCC($bcc);
}
$mail->addAttachment($filename);
$mail->Subject = "{$cfg['email_from_name']} - $dateToday";
$mail->Body = $body;
$mail->ErrorInfo;
$mail->IsHTML(true);
if(!$mail->Send()){
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']} Mailer Error: " . $mail->ErrorInfo . "\n";
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
} else {
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']} successfully sent ({$result} orders)\n";
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
}
} else {
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']} No order for today\n";
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
}

356
styles.css Normal file
View File

@@ -0,0 +1,356 @@
img {
border: none;
-ms-interpolation-mode: bicubic;
max-width: 100%;
}
body {
background-color: #f6f6f6;
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 12px;
line-height: 1.4;
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
width: 100%;
}
table {
border-collapse: separate;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
width: 100%;
}
table td {
font-family: sans-serif;
font-size: 10px;
vertical-align: top;
}
/* -------------------------------------
BODY & CONTAINER
------------------------------------- */
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
.container {
display: block;
margin: 0 auto !important;
/* makes it centered */
max-width: 880px;
padding: 10px;
width: 880px;
}
/* This should also be a block element, so that it will fill 100% of the .container */
.content {
box-sizing: border-box;
display: block;
margin: 0 auto;
max-width: 880px;
padding: 10px;
}
/* -------------------------------------
HEADER, FOOTER, MAIN
------------------------------------- */
.main {
background: #ffffff;
border-radius: 3px;
width: 100%;
}
.wrapper {
box-sizing: border-box;
padding: 20px;
}
.content-block {
padding-bottom: 10px;
padding-top: 10px;
}
.footer {
clear: both;
margin-top: 10px;
text-align: center;
width: 100%;
}
.footer td,
.footer p,
.footer span,
.footer a {
color: #999999;
font-size: 12px;
text-align: center;
}
/* -------------------------------------
TYPOGRAPHY
------------------------------------- */
h1,
h2,
h3,
h4 {
color: #000000;
font-family: sans-serif;
font-weight: 400;
line-height: 1.4;
margin: 0;
margin-bottom: 20px;
}
h1 {
font-size: 35px;
font-weight: 300;
text-align: center;
text-transform: capitalize;
}
p,
ul,
ol {
font-family: sans-serif;
font-size: 14px;
font-weight: normal;
margin: 0;
margin-bottom: 15px;
}
p li,
ul li,
ol li {
list-style-position: inside;
margin-left: 5px;
}
a {
color: #3498db;
text-decoration: underline;
}
/* -------------------------------------
BUTTONS
------------------------------------- */
.btn {
box-sizing: border-box;
width: 100%;
}
.btn > tbody > tr > td {
padding-bottom: 15px;
}
.btn table {
width: auto;
}
.btn table td {
background-color: #ffffff;
border-radius: 5px;
text-align: center;
}
.btn a {
background-color: #ffffff;
border: solid 1px #3498db;
border-radius: 5px;
box-sizing: border-box;
color: #3498db;
cursor: pointer;
display: inline-block;
font-size: 14px;
font-weight: bold;
margin: 0;
padding: 12px 25px;
text-decoration: none;
text-transform: capitalize;
}
.btn-primary table td {
background-color: #3498db;
}
.btn-primary a {
background-color: #3498db;
border-color: #3498db;
color: #ffffff;
}
/* -------------------------------------
OTHER STYLES THAT MIGHT BE USEFUL
------------------------------------- */
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.clear {
clear: both;
}
.mt0 {
margin-top: 0;
}
.mb0 {
margin-bottom: 0;
}
.preheader {
color: transparent;
display: none;
height: 0;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
mso-hide: all;
visibility: hidden;
width: 0;
}
.powered-by a {
text-decoration: none;
}
hr {
border: 0;
border-bottom: 1px solid #f6f6f6;
margin: 20px 0;
}
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class="body"] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class="body"] p,
table[class="body"] ul,
table[class="body"] ol,
table[class="body"] td,
table[class="body"] span,
table[class="body"] a {
font-size: 12px !important;
}
table[class="body"] .wrapper,
table[class="body"] .article {
padding: 10px !important;
}
table[class="body"] .content {
padding: 0 !important;
}
table[class="body"] .container {
padding: 0 !important;
width: 100% !important;
}
table[class="body"] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class="body"] .btn table {
width: 100% !important;
}
table[class="body"] .btn a {
width: 100% !important;
}
table[class="body"] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
.btn-primary table td:hover {
background-color: #34495e !important;
}
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important;
}
}
.table-bordered td,
th {
border: 1px solid black;
padding: 2px;
}
.previewImage {
height: 200px;
overflow: hidden;
object-fit: contain;
}
@media print {
.items tr {
page-break-inside: avoid;
position: relative;
}
}
@page {
size: 18cm 26.7cm;
margin: 1cm;
}
#tbl_subitem tr td {
text-align: center;
}