add all files

This commit is contained in:
Rucus
2026-02-17 09:29:34 -06:00
parent b8c8d67c67
commit 782d203799
21925 changed files with 2433086 additions and 0 deletions

31
lasuca/.env.example Normal file
View File

@@ -0,0 +1,31 @@
APP_NAME="LASUCA Portal"
APP_ENV=local
APP_DEBUG=true
DB_HOST=192.168.0.10
DB_PORT=3306
DB_NAME=scdb
DB_USERNAME=scdb
DB_PASSWORD=lasucasugar
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
CTR_DB_HOST=192.168.0.10
CTR_DB_PORT=3306
CTR_DB_NAME=controls
CTR_DB_USERNAME=scdb
CTR_DB_PASSWORD=lasucasugar
CTR_DB_CHARSET=utf8mb4
CTR_DB_COLLATION=utf8mb4_unicode_ci
SQLSRV_HOST=CBM2K12\\SQLEXPRESS
SQLSRV_DATABASE=SugarCaneScale
SQLSRV_USERNAME=cbmclient
SQLSRV_PASSWORD=ascbm2k
# JWT Configuration (CHANGE IN PRODUCTION!)
JWT_SECRET=your-secure-random-string-at-least-32-chars
JWT_ACCESS_EXPIRY=900
JWT_REFRESH_EXPIRY=2592000
FILES_STORAGE_PATH=storage

47
lasuca/.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,47 @@
# Copilot Instructions
## Project shape
- Legacy PHP 5.x site generated with Artisteer templates; public pages live at the repo root (`index.php`, `home.php`, etc.) and share `style.css`, `script.js`, and `menumain.php`/`menugrower.php` includes for navigation.
- Grower self-service lives under `grower-login.php` and per-grower folders in `growers/` (e.g. `growers/999/`). Each grower folder wraps shared includes but serves files and PDF listings via `dtrlist.php`.
- Reporting utilities are under `loaddata/`, mixing PHP views with SQL Server queries. Shared helper includes, credentials, and menu snippets sit in `inc/`.
- `lasucadev/` contains vendor-style experiments (e.g. `ping/`) that normally stay untouched; treat as third-party source.
- Modernized theme assets live under `inc/theme-header.php`, `inc/theme-footer.php`, and `inc/theme-toggle.php`; they pull in Bootstrap-based styles from `new/css/` and behaviour from `new/js/scripts.js`.
- Custom styling bundles include `new/css/lasuca-theme.css` for global look-and-feel, `new/css/grower-portal.css` for authenticated pages, and `new/css/farmdata.css` for the load-data explorer.
## Recent updates
- Grower portal pages (`grower-dashboard.php`, `grower-files.php`, `grower-account.php`, etc.) now use the shared theme header/footer, the protected navigation, and quick-link tiles; keep using those includes for any new grower tools.
- The dashboard greeting reads from the `growername` column; profile edits persist via `auth_update_profile`. Avoid reverting to the old `firstname` fallback.
- Factory data cards on the dashboard reuse the query logic from `milldata.php`; ensure any future tweaks go through the shared helper in `inc/grower_dashboard.php`.
- A light/dark mode toggle is available site-wide through `inc/theme-toggle.php` and `new/js/scripts.js`, persisting state via `localStorage` and body classes (`theme-dark` default, `theme-light` override).
- Branding updates place `images/header.png` behind the navbar, add subtle drop shadows, and give the logo depth—mirror that pattern if new headers are introduced.
- `farmdata/index.php` has been rebuilt with the new theme, richer filters (grower, crop day, vehicle, tract, load, overload threshold), query helpers, and SQLSRV stubs for environments lacking the driver.
## Runtime & tooling
- Target PHP ≤5.6: the code relies on deprecated `mysql_*` APIs and short open tags in places (`<?`). Do not replace with `mysqli`/PDO unless coordinating a full migration.
- Development happens by serving the repo root through Apache/PHP or via `php -S localhost:8000` (requires the `sqlsrv` extension and Microsoft drivers if exercising scale reports).
- There are no automated tests; validate changes by hitting the relevant PHP endpoint in a browser.
## Application flows
- Public site: static-like pages include `menumain.php` and echo content blocks. Follow the pattern in `index.php` when adding pages.
- Grower portal: `grower-login.php` authenticates against the `scdb.members` table and redirects to a directory matching the username. Any new grower assets must be placed inside that username folder and linked through `dtrlist.php` or `loads.php`.
- Load data reports (`loaddata/index.php`) connect to SQL Server (`CBM2K12\SQLEXPRESS`, database `SugarCaneScale`) and display tabular results while accumulating totals. Reuse that query pattern when adding filters or exports.
## Data access patterns
- MySQL credentials live in `inc/dbconfig.php` and are consumed by `inc/opendb.php`; pages using MySQL typically `include` both and call `mysql_query`. Maintain that include order so globals (`$dbhost`, `$dbuser`, …) are defined.
- SQL Server access always happens inline with `sqlsrv_connect` + `sqlsrv_query` (see `loaddata/index.php`). Remember to free statements and close connections when you introduce long-running loops.
- Directory-based reports rely on `inc/dtrlistconfig.php` and `inc/dtrlistfunctions.php`; expose new report folders by placing files under the appropriate `growers/<id>/<year>/` path and letting `dtrlist.php` pick them up.
## UI conventions
- Theme pages should load through `inc/theme-header.php`/`inc/theme-footer.php`, which already enqueue Bootstrap, the theme palette, and the light/dark toggle. Only fall back to Artisteer layouts when touching untouched legacy pages.
- Prefer the utility classes defined in `new/css/lasuca-theme.css` and `new/css/grower-portal.css` before adding inline styles. When legacy Artisteer selectors such as the `vtitle` ID remain, leave them in place until that page is fully migrated.
- Front-end behaviour now lives primarily in `new/js/scripts.js`; keep scripts simple, avoid module loaders, and update the toggle helpers if you add new theme-aware widgets.
## Security & legacy quirks
- Session gating uses `$_SESSION['ena']` alone (`session.php`); when adding new protected pages, include that file first to preserve the redirect-on-failure behavior.
- Input sanitization is minimal (manual `mysql_real_escape_string`); mimic the existing approach and note any improvements separately rather than mixing refactors into feature work.
- Credentials are hard-coded throughout; do not rotate them casually—coordinate with ops and document any changes prominently.
## When in doubt
- Mirror the structure of a neighboring file before introducing new patterns.
- Keep compatibility front-of-mind: new PHP features or libraries can break production if the runtime remains on PHP 5.x.
- Document any new data sources, includes, or cron assumptions inside this file so future agents stay oriented.

23
lasuca/api/.htaccess Normal file
View File

@@ -0,0 +1,23 @@
# Route all API requests to the router
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /api/
# Allow direct access to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Route everything to index.php
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
# Deny access to helper files directly
<FilesMatch "^(helpers|endpoints|migrations)">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
</FilesMatch>

View File

@@ -0,0 +1,51 @@
<?php
// phpcs:ignoreFile
/**
* POST /api/auth/login
*
* Authenticate user and return JWT tokens.
*/
declare(strict_types=1);
$body = api_get_json_body();
api_require_fields($body, ['username', 'password']);
$username = trim((string) $body['username']);
$password = (string) $body['password'];
// Attempt authentication
$member = auth_attempt_login($username, $password);
if ($member === null) {
api_error('Invalid username or password', 401);
}
// Generate tokens
$accessToken = jwt_create_access_token($member);
$refreshData = jwt_create_refresh_token($member);
// Store refresh token in database
$stored = jwt_store_refresh_token(
$member['username'],
$refreshData['token_id'],
$refreshData['expires_at']
);
if (!$stored) {
// Log but don't fail - access token still works
error_log('Failed to store refresh token for user: ' . $member['username']);
}
api_success([
'access_token' => $accessToken,
'refresh_token' => $refreshData['token'],
'token_type' => 'Bearer',
'expires_in' => 900, // 15 minutes in seconds
'user' => [
'username' => $member['username'],
'growerid' => $member['growerid'] ?? null,
'growername' => $member['growername'] ?? null,
'email' => $member['email'] ?? null,
],
]);

View File

@@ -0,0 +1,37 @@
<?php
// phpcs:ignoreFile
/**
* POST /api/auth/logout
*
* Revoke the current refresh token.
*/
declare(strict_types=1);
$body = api_get_json_body();
// If refresh token provided, revoke it specifically
if (isset($body['refresh_token']) && $body['refresh_token'] !== '') {
$refreshToken = trim((string) $body['refresh_token']);
$payload = jwt_decode_token($refreshToken);
if ($payload !== null && isset($payload['jti'])) {
jwt_revoke_refresh_token($payload['jti']);
}
}
// Optionally, if access token is valid, revoke all user tokens
$accessToken = jwt_get_bearer_token();
if ($accessToken !== null) {
$payload = jwt_decode_token($accessToken);
if ($payload !== null && isset($payload['sub'])) {
// If 'revoke_all' flag is set, revoke all tokens for this user
if (isset($body['revoke_all']) && $body['revoke_all'] === true) {
jwt_revoke_all_user_tokens($payload['sub']);
}
}
}
api_success(['message' => 'Logged out successfully']);

View File

@@ -0,0 +1,30 @@
<?php
// phpcs:ignoreFile
/**
* GET /api/auth/me
*
* Return current authenticated user information.
*/
declare(strict_types=1);
// Require valid access token
$tokenUser = jwt_require_auth();
// Fetch fresh user data from database
$member = auth_find_member($tokenUser['username']);
if ($member === null) {
api_error('User not found', 404);
}
api_success([
'user' => [
'username' => $member['username'],
'growerid' => $member['growerid'] ?? null,
'growername' => $member['growername'] ?? null,
'email' => $member['email'] ?? null,
'phone' => $member['phone'] ?? null,
'last_login_at' => $member['last_login_at'] ?? null,
],
]);

View File

@@ -0,0 +1,65 @@
<?php
// phpcs:ignoreFile
/**
* POST /api/auth/refresh
*
* Exchange a valid refresh token for a new access token.
*/
declare(strict_types=1);
$body = api_get_json_body();
api_require_fields($body, ['refresh_token']);
$refreshToken = trim((string) $body['refresh_token']);
// Decode the refresh token
$payload = jwt_decode_token($refreshToken);
if ($payload === null) {
api_error('Invalid or expired refresh token', 401);
}
if (!isset($payload['type']) || $payload['type'] !== 'refresh') {
api_error('Invalid token type', 401);
}
$username = $payload['sub'] ?? null;
$tokenId = $payload['jti'] ?? null;
if ($username === null || $tokenId === null) {
api_error('Invalid refresh token payload', 401);
}
// Verify token exists in database and is not revoked
if (!jwt_validate_refresh_token($username, $tokenId)) {
api_error('Refresh token has been revoked or does not exist', 401);
}
// Look up current user data
$member = auth_find_member($username);
if ($member === null) {
api_error('User no longer exists', 401);
}
// Revoke the old refresh token (rotation for security)
jwt_revoke_refresh_token($tokenId);
// Generate new tokens
$accessToken = jwt_create_access_token($member);
$newRefreshData = jwt_create_refresh_token($member);
// Store new refresh token
jwt_store_refresh_token(
$member['username'],
$newRefreshData['token_id'],
$newRefreshData['expires_at']
);
api_success([
'access_token' => $accessToken,
'refresh_token' => $newRefreshData['token'],
'token_type' => 'Bearer',
'expires_in' => 900,
]);

View File

@@ -0,0 +1,24 @@
<?php
// phpcs:ignoreFile
/**
* GET /api/health
*
* Health check endpoint for monitoring.
*/
declare(strict_types=1);
global $conn;
$dbStatus = 'ok';
if (!$conn || $conn->connect_errno) {
$dbStatus = 'error';
}
api_success([
'status' => 'ok',
'timestamp' => date('c'),
'database' => $dbStatus,
'version' => '1.0.0',
]);

263
lasuca/api/helpers/jwt.php Normal file
View File

@@ -0,0 +1,263 @@
<?php
// phpcs:ignoreFile
/**
* JWT Token Helpers
*/
declare(strict_types=1);
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
/**
* Get the JWT secret key from environment or fallback.
*/
function jwt_get_secret(): string
{
$secret = getenv('JWT_SECRET');
if ($secret === false || $secret === '') {
// Fallback for development - MUST be set in production
$secret = 'lasuca-dev-secret-change-in-production-' . md5(__DIR__);
}
return $secret;
}
/**
* Generate an access token for a user.
*/
function jwt_create_access_token(array $user): string
{
$issuedAt = time();
$expiresAt = $issuedAt + (15 * 60); // 15 minutes
$payload = [
'iss' => 'lasuca-api',
'iat' => $issuedAt,
'exp' => $expiresAt,
'sub' => $user['username'],
'type' => 'access',
'user' => [
'username' => $user['username'],
'growerid' => $user['growerid'] ?? null,
'growername' => $user['growername'] ?? null,
'email' => $user['email'] ?? null,
],
];
return JWT::encode($payload, jwt_get_secret(), 'HS256');
}
/**
* Generate a refresh token for a user.
*/
function jwt_create_refresh_token(array $user): array
{
$issuedAt = time();
$expiresAt = $issuedAt + (30 * 24 * 60 * 60); // 30 days
$tokenId = bin2hex(random_bytes(32));
$payload = [
'iss' => 'lasuca-api',
'iat' => $issuedAt,
'exp' => $expiresAt,
'sub' => $user['username'],
'type' => 'refresh',
'jti' => $tokenId,
];
$token = JWT::encode($payload, jwt_get_secret(), 'HS256');
return [
'token' => $token,
'token_id' => $tokenId,
'expires_at' => date('Y-m-d H:i:s', $expiresAt),
];
}
/**
* Validate and decode a JWT token.
*/
function jwt_decode_token(string $token): ?array
{
try {
$decoded = JWT::decode($token, new Key(jwt_get_secret(), 'HS256'));
return (array) $decoded;
} catch (ExpiredException $e) {
return null;
} catch (\Exception $e) {
return null;
}
}
/**
* Extract Bearer token from Authorization header.
*/
function jwt_get_bearer_token(): ?string
{
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER['Authorization']);
} elseif (isset($_SERVER['HTTP_AUTHORIZATION'])) {
$headers = trim($_SERVER['HTTP_AUTHORIZATION']);
} elseif (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
$requestHeaders = array_combine(
array_map('ucwords', array_keys($requestHeaders)),
array_values($requestHeaders)
);
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
if ($headers === null) {
return null;
}
if (preg_match('/Bearer\s+(\S+)/i', $headers, $matches)) {
return $matches[1];
}
return null;
}
/**
* Require valid access token and return user data.
*/
function jwt_require_auth(): array
{
$token = jwt_get_bearer_token();
if ($token === null) {
api_error('Authorization required', 401);
}
$payload = jwt_decode_token($token);
if ($payload === null) {
api_error('Invalid or expired token', 401);
}
if (!isset($payload['type']) || $payload['type'] !== 'access') {
api_error('Invalid token type', 401);
}
if (!isset($payload['user']) || !is_array((array) $payload['user'])) {
api_error('Invalid token payload', 401);
}
return (array) $payload['user'];
}
/**
* Store refresh token in database.
*/
function jwt_store_refresh_token(string $username, string $tokenId, string $expiresAt): bool
{
global $conn;
$sql = "INSERT INTO refresh_tokens (username, token_id, expires_at, created_at)
VALUES (?, ?, ?, NOW())";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
return false;
}
$stmt->bind_param('sss', $username, $tokenId, $expiresAt);
$success = $stmt->execute();
$stmt->close();
return $success;
}
/**
* Validate refresh token exists and is not revoked.
*/
function jwt_validate_refresh_token(string $username, string $tokenId): bool
{
global $conn;
$sql = "SELECT id FROM refresh_tokens
WHERE username = ?
AND token_id = ?
AND expires_at > NOW()
AND revoked_at IS NULL
LIMIT 1";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
return false;
}
$stmt->bind_param('ss', $username, $tokenId);
$stmt->execute();
$result = $stmt->get_result();
$exists = $result->num_rows > 0;
$stmt->close();
return $exists;
}
/**
* Revoke a specific refresh token.
*/
function jwt_revoke_refresh_token(string $tokenId): bool
{
global $conn;
$sql = "UPDATE refresh_tokens SET revoked_at = NOW() WHERE token_id = ?";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
return false;
}
$stmt->bind_param('s', $tokenId);
$success = $stmt->execute();
$stmt->close();
return $success;
}
/**
* Revoke all refresh tokens for a user.
*/
function jwt_revoke_all_user_tokens(string $username): bool
{
global $conn;
$sql = "UPDATE refresh_tokens SET revoked_at = NOW() WHERE username = ? AND revoked_at IS NULL";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
return false;
}
$stmt->bind_param('s', $username);
$success = $stmt->execute();
$stmt->close();
return $success;
}
/**
* Clean up expired tokens (call periodically).
*/
function jwt_cleanup_expired_tokens(): int
{
global $conn;
$sql = "DELETE FROM refresh_tokens WHERE expires_at < NOW()";
$result = $conn->query($sql);
return $result ? $conn->affected_rows : 0;
}

View File

@@ -0,0 +1,84 @@
<?php
// phpcs:ignoreFile
/**
* API Response Helpers
*/
declare(strict_types=1);
/**
* Send a JSON success response.
*/
function api_success(array $data = [], int $statusCode = 200): void
{
http_response_code($statusCode);
echo json_encode([
'success' => true,
'data' => $data,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit();
}
/**
* Send a JSON error response.
*/
function api_error(string $message, int $statusCode = 400, array $details = []): void
{
http_response_code($statusCode);
$response = [
'success' => false,
'error' => [
'message' => $message,
'code' => $statusCode,
],
];
if (!empty($details)) {
$response['error']['details'] = $details;
}
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit();
}
/**
* Get JSON body from request.
*/
function api_get_json_body(): array
{
$rawBody = file_get_contents('php://input');
if ($rawBody === '' || $rawBody === false) {
return [];
}
$decoded = json_decode($rawBody, true);
if (!is_array($decoded)) {
return [];
}
return $decoded;
}
/**
* Require specific fields in request body.
*/
function api_require_fields(array $body, array $fields): void
{
$missing = [];
foreach ($fields as $field) {
if (!isset($body[$field]) || (is_string($body[$field]) && trim($body[$field]) === '')) {
$missing[] = $field;
}
}
if (!empty($missing)) {
api_error('Missing required fields: ' . implode(', ', $missing), 422);
}
}

76
lasuca/api/index.php Normal file
View File

@@ -0,0 +1,76 @@
<?php
// phpcs:ignoreFile
/**
* LASUCA API Router
*
* Simple router for REST API endpoints.
* All requests to /api/* should be routed here via .htaccess or server config.
*/
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
// CORS headers for mobile/cross-origin requests
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
header('Access-Control-Max-Age: 86400');
// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit();
}
// Load dependencies
$rootDir = dirname(__DIR__);
if (file_exists($rootDir . '/vendor/autoload.php')) {
require_once $rootDir . '/vendor/autoload.php';
}
require_once $rootDir . '/inc/dbconfig.php';
require_once $rootDir . '/inc/opendb.php';
require_once $rootDir . '/api/helpers/response.php';
require_once $rootDir . '/api/helpers/jwt.php';
require_once $rootDir . '/inc/auth.php';
// Parse the request path
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
$scriptName = $_SERVER['SCRIPT_NAME'] ?? '';
// Remove query string
$path = parse_url($requestUri, PHP_URL_PATH);
// Remove /api prefix and normalize
$basePath = dirname($scriptName);
if ($basePath !== '/') {
$path = substr($path, strlen($basePath));
}
$path = '/' . trim(str_replace('/api', '', $path), '/');
$method = $_SERVER['REQUEST_METHOD'];
// Simple route matching
$routes = [
'POST /auth/login' => 'auth/login.php',
'POST /auth/refresh' => 'auth/refresh.php',
'POST /auth/logout' => 'auth/logout.php',
'GET /auth/me' => 'auth/me.php',
'GET /health' => 'health.php',
];
$routeKey = $method . ' ' . $path;
if (isset($routes[$routeKey])) {
$handlerPath = $rootDir . '/api/endpoints/' . $routes[$routeKey];
if (file_exists($handlerPath)) {
require $handlerPath;
} else {
api_error('Endpoint not implemented', 501);
}
} else {
api_error('Not found', 404);
}

View File

@@ -0,0 +1,22 @@
-- LASUCA API: Refresh Tokens Table
-- Run this migration to add JWT refresh token storage
CREATE TABLE IF NOT EXISTS refresh_tokens (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL,
token_id VARCHAR(64) NOT NULL UNIQUE,
expires_at DATETIME NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
revoked_at DATETIME NULL DEFAULT NULL,
INDEX idx_username (username),
INDEX idx_token_id (token_id),
INDEX idx_expires_at (expires_at),
FOREIGN KEY (username) REFERENCES members(username) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Optional: Add password reset columns to members table for Phase 2
-- ALTER TABLE members
-- ADD COLUMN password_reset_token VARCHAR(64) NULL DEFAULT NULL,
-- ADD COLUMN password_reset_expires DATETIME NULL DEFAULT NULL;

182
lasuca/blank.php Normal file
View File

@@ -0,0 +1,182 @@
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta name="generator"
content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<!-- Created by Artisteer v4.3.0.60745 -->
<meta charset="utf-8" />
<title>New Page</title>
<meta name="viewport" content="initial-scale = 1.0, maximum-scale = 1.0, user-scalable = no, width = device-width" />
<!--[if lt IE 9]><script src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<link rel="stylesheet" href="style.css" media="screen" />
<!--[if lte IE 7]><link rel="stylesheet" href="style.ie7.css" media="screen" /><![endif]-->
<link rel="stylesheet" href="style.responsive.css" media="all" />
<script src="jquery.js"></script>
<script src="script.js"></script>
<script src="script.responsive.js"></script>
</head>
<body>
<div id="art-main">
<header class="art-header">
<div class="art-shapes">
<div class="art-object1090304479"></div>
</div>
<h1 class="art-headline">
<a href="/">Producers of Raw Cane Sugar and Black Strap Molasses</a>
</h1>
</header>
<?php include("menumain.php"); ?>
<div class="art-sheet clearfix">
<div class="art-layout-wrapper">
<div class="art-content-layout">
<div class="art-content-layout-row">
<div class="art-layout-cell art-content">
<article class="art-post art-article">
<div class="art-postcontent art-postcontent-0 clearfix">
<h1>Company Personnel</h1>
<p>
<br />
</p>
</div>
<div class="art-content-layout">
<div class="art-content-layout-row">
<div class="art-layout-cell layout-item-1" style="width: 33%" >
<h2 align="center">Executives</h2>
<div align="center">
<br>
<i><u>President</u></i>
<br>
<strong>Michael G Melancon</strong>
<br><br>
<i><u>Vice President</u></i>
<br>
<strong>Ross Harper</strong>
<br>
<br>
<i><u>Secretary</u></i>
<br>
<strong>Andre Blanchard</strong>
<br>
<br>
<i><u>Treasurer</u></i>
<br>
<strong>Dane Berard</strong>
<br>
<br>
<i><u>Directors</u></i>
<br>
<strong>Curry Albert</strong>
<br>
<strong>Andre Blanchard</strong>
<br>
<strong>Terrel Borel</strong>
<br>
<strong>Justin Frederick</strong>
<br>
<strong>Daniel Dupont</strong>
<br>
<strong>Roy Latiolas</strong>
<br>
<strong>Ross Harper</strong>
<br>
<strong>Tim Bourque</strong>
<br>
<strong>Bernard Laviolette Jr</strong>
<br>
<strong>Danny Walet</strong>
<br>
<strong>Craig Melancon</strong>
<br>
<strong>Charlie Levert</strong>
</div>
</div>
<div class="art-layout-cell layout-item-2" style="width: 33%" >
<h2 align="center">Management</h2>
<div align="center">
<br>
<em><u>General Manager</u></em>
<br>
<strong>Michael Comb</strong>
<br>
<br>
<u><em>Plant Manager</em></u>
<br>
<strong>Glenn Judice</strong>
<br>
<br>
<u><em>Supervisors</em></u>
<br>
<strong>Nolis Champagne</strong>
<br>
<strong>Brian Gonsuron</strong>
<br>
<strong>Bobby Bennett</strong>
<br>
<br>
<u><em>Grower Relations</em></u>
<br>
<strong>Jeff Broussard</strong>
<br>
<br>
<u><em>Chief Chemist and Process Superintendant</em></u>
<br>
<strong>Antonio Avila</strong>
<br>
<br>
<u><em>Purchasing Manager</em></u>
<br>
<strong>John LeVasseur</strong>
<br>
<br>
<u><em>Network Administrator</em></u>
<br>
<strong>Corey Verret</strong>
<br>
<br>
<u><em>Office Manager</em></u>
<br>
<strong>Linda Poirrier</strong>
<br>
<br>
<u><em>Environmental - Process Engineer</em></u>
<br>
<strong>Fikadu M. Beyene</strong>
</div>
</div>
<div class="art-layout-cell layout-item-2" style="width: 33%" >
<h2 align="center">Consultants</h2>
<div align="center">
<br>
<u><em>Consultants</em></u>
<br>
<br>
<strong>Harold Birkett</strong>
<br>
<br>
<strong>Luis Rivas</strong>
<br>
<br>
<strong>Glen Delaune</strong>
<br>
<br>
<strong>Alan Cook - Control Systems Consultants</strong>
<br>
</div>
</div>
</div>
</div>
</div>
</article>
</div>
</div>
</div>
</div>
</div>
<footer class="art-footer">
<div class="art-footer-inner">
<p>Copyright © 2012. Louisiana Sugar Cane Cooperative Inc. All Rights Reserved.</p>
</div>
</footer>
</div>
</body>
</html>

18
lasuca/composer.json Normal file
View File

@@ -0,0 +1,18 @@
{
"name": "lasuca/website",
"description": "Modernized LASUCA web portal upgrade",
"type": "project",
"require": {
"php": "^8.2",
"vlucas/phpdotenv": "^5.6",
"firebase/php-jwt": "^6.10"
},
"autoload": {
"psr-4": {
"App\\": "src/"
},
"files": [
"src/Support/helpers.php"
]
}
}

557
lasuca/composer.lock generated Normal file
View File

@@ -0,0 +1,557 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "a247bec296de64f11f24501ce03c6c16",
"packages": [
{
"name": "firebase/php-jwt",
"version": "v6.11.1",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
"reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66",
"reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66",
"shasum": ""
},
"require": {
"php": "^8.0"
},
"require-dev": {
"guzzlehttp/guzzle": "^7.4",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.5",
"psr/cache": "^2.0||^3.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0"
},
"suggest": {
"ext-sodium": "Support EdDSA (Ed25519) signatures",
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
},
"type": "library",
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"keywords": [
"jwt",
"php"
],
"support": {
"issues": "https://github.com/firebase/php-jwt/issues",
"source": "https://github.com/firebase/php-jwt/tree/v6.11.1"
},
"time": "2025-04-09T20:32:01+00:00"
},
{
"name": "graham-campbell/result-type",
"version": "v1.1.3",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
"reference": "3ba905c11371512af9d9bdd27d99b782216b6945"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945",
"reference": "3ba905c11371512af9d9bdd27d99b782216b6945",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.3"
},
"require-dev": {
"phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
},
"type": "library",
"autoload": {
"psr-4": {
"GrahamCampbell\\ResultType\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "An Implementation Of The Result Type",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
"Result Type",
"Result-Type",
"result"
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
"type": "tidelift"
}
],
"time": "2024-07-20T21:45:45+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.9.4",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/php-option.git",
"reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
"reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
},
"branch-alias": {
"dev-master": "1.9-dev"
}
},
"autoload": {
"psr-4": {
"PhpOption\\": "src/PhpOption/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Johannes M. Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh"
},
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "Option Type for PHP",
"keywords": [
"language",
"option",
"php",
"type"
],
"support": {
"issues": "https://github.com/schmittjoh/php-option/issues",
"source": "https://github.com/schmittjoh/php-option/tree/1.9.4"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
"type": "tidelift"
}
],
"time": "2025-08-21T11:53:16+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
"shasum": ""
},
"require": {
"ext-iconv": "*",
"php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-12-23T08:48:59+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2025-01-02T08:10:11+00:00"
},
{
"name": "vlucas/phpdotenv",
"version": "v5.6.2",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
"reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
"reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
"shasum": ""
},
"require": {
"ext-pcre": "*",
"graham-campbell/result-type": "^1.1.3",
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.3",
"symfony/polyfill-ctype": "^1.24",
"symfony/polyfill-mbstring": "^1.24",
"symfony/polyfill-php80": "^1.24"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-filter": "*",
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"suggest": {
"ext-filter": "Required to use the boolean validator."
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
},
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Dotenv\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Vance Lucas",
"email": "vance@vancelucas.com",
"homepage": "https://github.com/vlucas"
}
],
"description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
"keywords": [
"dotenv",
"env",
"environment"
],
"support": {
"issues": "https://github.com/vlucas/phpdotenv/issues",
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
"type": "tidelift"
}
],
"time": "2025-04-30T23:37:27+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^8.2"
},
"platform-dev": {},
"plugin-api-version": "2.6.0"
}

74
lasuca/contact-us.php Normal file
View File

@@ -0,0 +1,74 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Contact LASUCA';
$metaDescription = 'Reach the Louisiana Sugar Cane Cooperative by phone, email, or our contact form.';
$activeNav = 'contact';
require __DIR__ . '/inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">We&rsquo;re here to help</span>
<h1>Contact the Louisiana Sugar Cane Cooperative</h1>
<p>
Have a question about deliveries, membership, or operations? Reach out to our team and we&rsquo;ll
connect you with the right specialist.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="row g-4 align-items-start">
<div class="col-lg-5">
<div class="contact-card h-100">
<h2 class="h4 mb-3">Main office</h2>
<p class="mb-3">
Louisiana Sugar Cane Cooperative<br />
6092 Resweber Hwy<br />
St. Martinville, LA 70582
</p>
<p class="mb-2"><strong>Phone:</strong> (337) 394-3785</p>
<p class="mb-2"><strong>Fax:</strong> (337) 394-5692</p>
<p class="mb-2"><strong>Email:</strong> <a href="mailto:info@lasuca.com">info@lasuca.com</a></p>
<p class="mb-0"><strong>Web:</strong> <a href="https://www.lasuca.com">www.lasuca.com</a></p>
</div>
</div>
<div class="col-lg-7">
<div class="content-card h-100">
<h2 class="h4 mb-3">Send us a message</h2>
<p>
Complete the form and a member of the cooperative will reach back within one business day
during the grinding season.
</p>
<form method="post" action="contactengine.php" class="row g-3">
<div class="col-md-6">
<label for="Name" class="form-label">Name</label>
<input type="text" class="form-control" id="Name" name="Name" required />
</div>
<div class="col-md-6">
<label for="City" class="form-label">City</label>
<input type="text" class="form-control" id="City" name="City" />
</div>
<div class="col-12">
<label for="Email" class="form-label">Email</label>
<input type="email" class="form-control" id="Email" name="Email" required />
</div>
<div class="col-12">
<label for="Message" class="form-label">Message</label>
<textarea class="form-control" id="Message" name="Message" rows="6" required></textarea>
</div>
<div class="col-12">
<button type="submit" name="submit" class="btn btn-primary btn-lg">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/inc/theme-footer.php';
?>

View File

@@ -0,0 +1,184 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Cane Handling';
$metaDescription = 'See how LASUCA receives, scales, and prepares cane for milling.';
$activeNav = 'factory';
require __DIR__ . '/inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Cane handling</h1>
<p>
Efficient receiving keeps fresh cane moving. From calibrated scales to automated feeders,
the LASUCA yard turns deliveries into reliable throughput for the mills.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="row g-4 align-items-center">
<div class="col-lg-6">
<div class="content-card">
<h2 class="h4">Scales tuned for modern hauling</h2>
<p>
The cane yard operates a Fairbanks platform scale for tractor wagons and truck trailers,
alongside a dedicated 100-ton Fairbanks cane scale installed in 1992. These calibrated stations
keep inbound weights accurate, traceable, and ready for ticketing.
</p>
<p class="mb-0">
Cane arrives in chain-net wagons or trucks and is routed to one of two stationary dump stations
or three direct-feed dump tables. Payloaders equipped with Cameco grabs and cleanup buckets keep
the yard moving between loads.
</p>
</div>
</div>
<div class="col-lg-6 text-center">
<img src="/images/handling1-4-large.jpg" alt="Cane unloading at LASUCA" class="img-fluid content-image" />
</div>
</div>
</div>
</section>
<section class="page-section-dark py-5">
<div class="container">
<div class="row g-4 align-items-center">
<div class="col-lg-6 order-lg-2">
<div class="content-card">
<h2 class="h4">Automated flow to the carrier</h2>
<p>
Each dump table is controlled by load cells on the main carrier, automating cane flow to match
mill demand. Cane is washed before it reaches the carrier, improving cleanliness and preparation
while reducing wear.
</p>
<p class="mb-0">
A 70-foot drive-through rear truck dumper, commissioned for the 2002 crop, handles 50-ton loads at
a 63° tilt. Operators can feed the main carrier immediately or divert to yard storage via apron
conveyor when inventories need to build.
</p>
</div>
</div>
<div class="col-lg-6 order-lg-1 text-center">
<img src="/images/handling2-2-large.jpg" alt="Automated cane handling equipment" class="img-fluid content-image" />
</div>
</div>
</div>
</section>
<section class="page-section py-5">
<div class="container">
<div class="row g-4 align-items-center">
<div class="col-lg-6">
<img src="/images/handling3-2-large.jpg" alt="Cane preparation knives" class="img-fluid content-image" />
</div>
<div class="col-lg-6">
<div class="content-card">
<h2 class="h4">Preparation built for throughput</h2>
<p>
Cane is conditioned by three sets of preparation knives, each tuned for consistent fiber size and
extraction:
</p>
<ul class="feature-list">
<li>
<span class="icon">1</span>
<div>First knife 1000 hp, 600 rpm, 32 blades cutting 20 inches from the carrier slats.</div>
</li>
<li>
<span class="icon">2</span>
<div>Second knife 1400 hp, 600 rpm, 54 blades trimming within one inch of the slats.</div>
</li>
<li>
<span class="icon">3</span>
<div>Third knife 1400 hp, 600 rpm, 96 blades making the final three-quarter inch cut.</div>
</li>
</ul>
<p class="mb-0">
The carrier angle and belt magnet were upgraded in 1995 to complement the knife modifications and
keep magnetic debris away from the first mill.
</p>
</div>
</div>
</div>
</div>
</section>
<section class="page-section-light py-5 border-top">
<div class="container">
<h2 class="h4 mb-4">Explore more factory systems</h2>
<div class="row g-3 row-cols-1 row-cols-md-2 row-cols-lg-3">
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/milling-equipment.php">
<h3 class="h5">Milling equipment</h3>
<p class="mb-0">Six-mill tandem, hydraulic drives, and Donnelly controls that power extraction.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/steam-plant.php">
<h3 class="h5">Steam plant</h3>
<p class="mb-0">Bagasse-fired boilers, natural gas backup, and ash handling infrastructure.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/clarification.php">
<h3 class="h5">Clarification</h3>
<p class="mb-0">Heaters, multifeed clarifiers, and vacuum filters conditioning raw juice.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/evaporation.php">
<h3 class="h5">Evaporation</h3>
<p class="mb-0">Pre-evaporators, triple effects, and automated vacuum pans concentrating syrup.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/centrifugals.php">
<h3 class="h5">Centrifugals</h3>
<p class="mb-0">Automatic batch and continuous machines polishing every massecuite grade.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/crystalizers.php">
<h3 class="h5">Crystallizers</h3>
<p class="mb-0">Receiver capacity and continuous banks keeping massecuite conditioned.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/pan-supply-tanks.php">
<h3 class="h5">Pan supply tanks</h3>
<p class="mb-0">Balanced syrup and molasses storage that feeds the pan floor.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/bagasse-storage.php">
<h3 class="h5">Bagasse storage</h3>
<p class="mb-0">Covered storage and reclaim systems feeding the boilers year-round.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/final-storage.php">
<h3 class="h5">Final storage</h3>
<p class="mb-0">Warehouse and tank capacity that stage raw sugar and molasses for shipment.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/vacuum-and-condensing.php">
<h3 class="h5">Vacuum &amp; condensing</h3>
<p class="mb-0">Spray ponds, ejectors, and injection pumps supporting stable vacuum.</p>
</a>
</div>
<div class="col">
<a class="content-card h-100 text-decoration-none text-reset d-block" href="/factory-information/miscelaneous.php">
<h3 class="h5">Fire protection &amp; utilities</h3>
<p class="mb-0">Emergency pumping and sprinkler systems safeguarding the factory.</p>
</a>
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/inc/theme-footer.php';
?>

View File

@@ -0,0 +1,46 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Bagasse Storage';
$metaDescription = 'Covered storage and reclaim systems keep LASUCAs bagasse ready for fuel and fiber use.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Bagasse storage</h1>
<p>
Purpose-built steel structures and a variable-speed reclaim system protect our bagasse inventory and keep
fuel flowing to the boilers.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="row g-5 align-items-center">
<div class="col-lg-6">
<div class="content-card">
<p>
A 75&nbsp;×&nbsp;75&nbsp;×&nbsp;35-foot all-steel building, constructed in 1992, houses the bagasse reclaiming system. The
6-foot by 80-foot bin conveyor uses a variable-speed hydraulic drive to keep material moving smoothly
toward the steam plant.
</p>
<p>
In 2002, an additional 71&nbsp;×&nbsp;50&nbsp;×&nbsp;37-foot steel extension was added on the north side of the original
structure, expanding covered storage and improving fuel reliability during wet weather windows.
</p>
</div>
</div>
<div class="col-lg-6 text-center">
<img src="/images/handling2-2-large.jpg" alt="Covered bagasse storage building" class="img-fluid content-image" />
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,46 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Centrifugals';
$metaDescription = 'Batch and continuous centrifugals polish sugar at LASUCA with upgraded Broadbent and Western States stations.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Centrifugals</h1>
<p>
Automated batch and continuous machines handle every massecuite grade, delivering clean crystals and
efficient molasses separation.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<h2 class="h4">Stations and capacity</h2>
<p>
LASUCA operates a seven-machine battery of 48&nbsp;×&nbsp;36-inch Western States automatic batch centrifugals for “A” and
“B” massecuites. Capacity increased again in 2001 with the addition of a C46 MT Broadbent automatic
batch machine.
</p>
<p>The low-grade station includes:</p>
<ul>
<li>Western States CC5 continuous centrifugal</li>
<li>Western States CC6 continuous centrifugal</li>
<li>Broadbent SPV 1220 continuous machine installed in 2001 (replacing a Western States CC2)</li>
</ul>
<p>
Together these machines keep the pan floor moving, recovering sugar while protecting molasses quality for
storage and sale.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,44 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Clarification';
$metaDescription = 'Clarifiers, heaters, and rotary vacuum filters prepare LASUCA juice for evaporation.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Clarification</h1>
<p>
High-capacity heaters, multi-compartment clarifiers, and rotary vacuum filters keep our juice clean and ready
for evaporation.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<p>
Juice from the milling tandem is stored in a 1,602&nbsp;cubic-foot (11,980 gallon) liming tank before moving
through two 2,500&nbsp;sq. ft. heaters and two additional 5,000&nbsp;sq. ft. heaters.
</p>
<p>
Clarification relies on a 24-foot Dorr multifeed clarifier, a 30-foot Graver clarifier, and a 26-foot
Rapi-Dorr installed for the 2002 crop. Each unit uses upgraded drawdown boxes and mud pumps to boost
capacity and uptime.
</p>
<p>
Solids removal is finished by a bank of rotary vacuum filters&mdash;10&nbsp;×&nbsp;16, 10&nbsp;×&nbsp;18, and 12&nbsp;×&nbsp;16-foot
Eimco units. Bagacillo sourced from the steam plant carriers supports consistent cake formation before
disposal.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,39 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Crystallizers';
$metaDescription = 'Receiver capacity and continuous crystallizer banks keep massecuite conditioned for centrifugals.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Crystallizers</h1>
<p>
Continuous banks of Dyer-Blanchard crystallizers finish “C” strikes and deliver steady massecuite flow to the
centrifugals.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<p>
A large receiver positioned above the crystallizer gallery catches every “C” strike and was expanded to
6,205&nbsp;cubic feet for the 2002 crop. From there the massecuite feeds two banks of seven
Dyer-Blanchard crystallizers, each holding 1,000&nbsp;cubic feet.
</p>
<p>
The banks operate in continuous flow, with Nadler pumps moving conditioned massecuite from the
crystallizer room to the centrifugal mixers to keep the station balanced.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,50 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Evaporation';
$metaDescription = 'Large-surface evaporators and automated vacuum pans drive LASUCA syrup concentration.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Evaporation</h1>
<p>
High-capacity pre-evaporators, triple effects, and automated vacuum pans concentrate clarified juice into
strike-ready syrup.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<h2 class="h4">Evaporator station</h2>
<p>
The station combines two 25,000&nbsp;sq. ft. pre-evaporators (one installed new in 2001), a 28,500&nbsp;sq. ft.
triple effect, and a 38,500&nbsp;sq. ft. triple effect&mdash;delivering 117,000&nbsp;sq. ft. of total heating surface.
</p>
<h2 class="h4 mt-4">Vacuum pans</h2>
<p>
Eight vacuum pans provide flexibility across product grades:
</p>
<ul>
<li>700 and 900&nbsp;cubic-foot pans</li>
<li>Two 1,100&nbsp;cubic-foot pans</li>
<li>One 1,200&nbsp;cubic-foot pan</li>
<li>Two 2,000&nbsp;cubic-foot pans</li>
<li>One 3,000&nbsp;cubic-foot pan</li>
</ul>
<p>
All discharge and cut-over valves operate with air-hydraulic systems. Pans five through eight are automated
with a Smar control platform from Brazil for tighter strikes and syrup consistency.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,40 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Final Storage';
$metaDescription = 'Warehouse and tank capacity keeps LASUCA sugar and molasses moving to market.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Final storage</h1>
<p>
Purpose-built warehouses and high-capacity tanks ensure raw sugar and molasses stay on schedule for shipment.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<h2 class="h4">Sugar handling</h2>
<p>
Raw sugar moves by belt to exterior holding bins fitted with hydraulic dump gates for fast truck loading.
Warehousing includes a 120&nbsp;×&nbsp;509-foot building installed in 1992, a 150&nbsp;×&nbsp;450-foot warehouse added in 2001,
and a 150&nbsp;×&nbsp;400-foot facility in Breaux Bridge.
</p>
<h2 class="h4 mt-4">Molasses storage</h2>
<p>
Bulk molasses capacity totals more than 3.5&nbsp;million gallons across tanks sized at 140,000, 390,000,
1,000,000, and 2,000,000 gallons (the largest installed in 1997).
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,59 @@
<nav class="art-nav">
<div class="art-nav-inner">
<ul class="art-hmenu">
<li>
<a href="../home.php">Home</a>
</li>
<li>
<a href="../factory-information.php">Factory Information</a>
<ul>
<li>
<a href="milling-equipment.php">Milling Equipment</a>
</li>
<li>
<a href="steam-plant.php">Steam Plant</a>
</li>
<li>
<a href="bagasse-storage.php">Bagasse Storage</a>
</li>
<li>
<a href="clarification.php">Clarification</a>
</li>
<li>
<a href="evaporation.php">Evaporation</a>
</li>
<li>
<a href="vacuum-and-condensing.php">Vacuum and Condensing</a>
</li>
<li>
<a href="pan-supply-tanks.php">Pan Supply Tanks</a>
</li>
<li>
<a href="crystalizers.php">Crystalizers</a>
</li>
<li>
<a href="centrifugals.php">Centrifugals</a>
</li>
<li>
<a href="final-storage.php">Final Storage</a>
</li>
<li>
<a href="miscelaneous.php">Miscelaneous</a>
</li>
</ul>
</li>
<li>
<a href="../production.php">Production</a>
</li>
<li>
<a href="../grower-login.php">Grower Login</a>
</li>
<li>
<a href="personnel.php">Personnel</a>
</li>
<li>
<a href="../contact-us.php">Contact Us</a>
</li>
</ul>
</div>
</nav>

View File

@@ -0,0 +1,90 @@
<!DOCTYPE html>
<html dir="ltr" lang="en-US"><head><!-- Created by Artisteer v4.3.0.60745 -->
<meta charset="utf-8">
<title>Milling Equipment</title>
<meta name="viewport" content="initial-scale = 1.0, maximum-scale = 1.0, user-scalable = no, width = device-width">
<!--[if lt IE 9]><script src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<link rel="stylesheet" href="../style.css" media="screen">
<!--[if lte IE 7]><link rel="stylesheet" href="../style.ie7.css" media="screen" /><![endif]-->
<link rel="stylesheet" href="../style.responsive.css" media="all">
<script src="../jquery.js"></script>
<script src="../script.js"></script>
<script src="../script.responsive.js"></script>
</head>
<body>
<div id="art-main">
<header class="art-header">
<div class="art-shapes">
<div class="art-object1090304479"></div>
</div>
<h1 class="art-headline">
<a href="/">Producers of Raw Cane Sugar and Black Strap Molasses</a>
</h1>
</header>
<?php // phpcs:ignoreFile
$pageTitle = 'Milling Equipment';
$metaDescription = 'Explore the six-mill tandem that powers LASUCAs extraction system.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Milling equipment</h1>
<p>
LASUCA&rsquo;s six-mill tandem mixes classic Donnelly chute design with modern hydraulic drives and
turbine power to keep extraction efficient and reliable.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="row g-4 align-items-start">
<div class="col-lg-7">
<div class="content-card">
<h2 class="h4">The milling tandem</h2>
<p>The milling tandem consists of the following:</p>
<ul>
<li>Mill No. 1 is a 7-foot three-roll mill (1995) with Donnelly chute and a 2,500 hp multi-stage turbine driving Horsburgh &amp; Scott gearboxes. Roll diameters: 46 inches.</li>
<li>Mill Nos. 2 and 3 are 6.5-foot mills with force-feed rolls and 40-inch roll diameters.</li>
<li>Mill No. 4 is a 7-foot mill driven by Hagglunds hydraulics (MB1150 and MB566 motors) powered by a 1,200 hp Elliott turbine and David Brown gearbox. Roll diameters: 44 inches.</li>
<li>Mill No. 5 is a 7-foot mill with 44-inch rolls, powered by a 1,400 hp Elliott turbine and Horsburgh &amp; Scott gearboxes, featuring an offside crown wheel force-feed roll.</li>
<li>Mill No. 6 is a Skoda mill with 7-foot by 48-inch rolls, driven by a 2,500 hp multi-stage turbine and offside crown wheel force-feed roll.</li>
</ul>
<p>
All six mills use Donnelly chutes with probe-controlled feed rates and rubber-belt conveyors set at
60°. Grooving is tuned to each mill: the first three use 3-inch pitch, 45° grooves; the last three
use 2-inch pitch, 45° grooves. All cane rolls include messchaert juice grooves measuring 1/2 inch by
1 inch.
</p>
</div>
</div>
<div class="col-lg-5 text-center">
<img src="/images/handling1-4-large.jpg" alt="LASUCA milling tandem" class="img-fluid content-image" />
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,39 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Miscellaneous Systems';
$metaDescription = 'Fire protection and emergency pumping capacity safeguard LASUCA operations.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Fire protection &amp; utilities</h1>
<p>
Dedicated pumps, hydrants, and sprinkler systems protect the factory complex and support rapid emergency
response.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<p>
Two high-capacity pumps deliver up to 4,000&nbsp;gpm at 100&nbsp;feet of head using water from Bayou Teche or the
nearby industrial park loop. Hose outlets are located throughout the facility to cover exterior and
interior hazards.
</p>
<p>
Additional safety comes from a dry-type sprinkler system supplied by a 1,000&nbsp;gpm diesel engine-driven
vertical pump, ready for rapid activation when needed.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,38 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Pan Supply Tanks';
$metaDescription = 'Syrup and molasses tankage keeps the pan floor supplied at LASUCA.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Pan supply tanks</h1>
<p>
Balanced syrup, A molasses, and B molasses storage keeps the pan floor charged for continuous strikes.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<p>
Two syrup tanks provide 35,836 gallons of storage, giving the pan floor buffer capacity between
clarification and boiling operations.
</p>
<p>
A molasses is stored in twin tanks totaling 25,658 gallons, while B molasses relies on two tanks totaling
26,544 gallons. Combined magma and seed storage on the pan floor adds another 7,842&nbsp;cubic feet of
capacity for process control.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,42 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Steam Plant';
$metaDescription = 'Bagasse-fired boilers with scrubbers and ash handling keep the LASUCA factory running.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Steam plant</h1>
<p>
Bagasse-fired boilers, natural gas backup, and ash handling systems provide reliable steam for every station.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<p>
The St. Martin steam plant features three 1,500&nbsp;hp boilers (two with incline pinhole grates for bagasse
and one Detroit stoker), one 1,300&nbsp;hp boiler with incline pinhole grates, and two 800&nbsp;hp horseshoe-furnace
boilers.
</p>
<p>
Each boiler includes induced-draft fans, fly-ash removal linked to individual scrubbers, and air pre-heaters.
All units can switch to natural gas when required.
</p>
<p>
Ash removal relies on screw conveyors beneath the floor feeding slat conveyors that deliver material to a
centralized gathering tank outside the boiler room.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

View File

@@ -0,0 +1,43 @@
<?php // phpcs:ignoreFile
$pageTitle = 'Vacuum & Condensing';
$metaDescription = 'Cooling water, ejectors, and spray pond capacity maintain vacuum for LASUCA pans and evaporators.';
$activeNav = 'factory';
require __DIR__ . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Factory information</span>
<h1>Vacuum &amp; condensing</h1>
<p>
High-volume condensers, ejectors, and spray pond capacity maintain dependable vacuum across pans and
evaporators.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="content-card">
<p>
Eight vacuum pans ranging from 700 to 3,000&nbsp;cubic feet use air-hydraulic cutover valves, with pans five
through eight automated via a Smar control system.
</p>
<p>
Individual condensers and Schutte &amp; Koerting ejectors serve both evaporators and pans, with an additional
ejector dedicated to rapid pan station pull-downs.
</p>
<p>
A redesigned spray pond delivers 35,280&nbsp;gpm of cooling capacity. Seven pumps totaling 53,580&nbsp;gpm recirculate
water, while injection pumps capable of 47,500&nbsp;gpm feed condensers, supplemented by treated makeup
water as needed.
</p>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/../inc/theme-footer.php';
?>

BIN
lasuca/farmdata/Thumbs.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,35 @@
<?php
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
$sql = "SELECT DISTINCT CropDay FROM LoadData ORDER BY CropDay DESC";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
echo "<select name='cropday' id='cropday'>";
echo '<option selected disabled value="">Crop Day...</option>';
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
echo "<option value='" . $row['CropDay'] . "' >" . $row['CropDay'] . "</option>";
}
echo "</select>";
//end
?>
<?
$db = null;
?>

View File

@@ -0,0 +1,22 @@
<?php
$dbName = "G:\CBM\SC\data\D_SCALE.mdb";
if (!file_exists($dbName)) {
die("Could not find database file.");
}
$db = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$dbName; Uid=; Pwd=;");
//select data from db
$day = "SELECT DISTINCT `Crop Day` FROM `Load Data` ORDER BY `Crop Day` DESC";
$cd = $db->query($day);
//end
echo "<select name='cropday'>";
echo '<option selected disabled value="">Crop Day...</option>';
while ($row = $cd->fetch()) {
echo "<option value='" . $row['Crop Day'] . "' >" . $row['Crop Day'] . "</option>";
}
echo "</select>";

View File

@@ -0,0 +1,3 @@
<div class="footer">
<p>Copyright © 2015, Louisiana Sugarcane Cooperative, Inc</p>
</div>

View File

@@ -0,0 +1,34 @@
<?php
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
$sql = "SELECT DISTINCT AccountName FROM Tract";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
echo "<select name='grower' id='grower'>";
echo '<option selected disabled value="">Select Farmer...</option>';
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
echo "<option value='" . $row['AccountName'] . "' >" . $row['AccountName'] . "</option>";
}
echo "</select>";
//end
?>
<?
$db = null;
?>

View File

@@ -0,0 +1,21 @@
<?php
$dbName = "G:\CBM\SC\data\D_SCALE.mdb";
if (!file_exists($dbName)) {
die("Could not find database file.");
}
$db = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$dbName; Uid=; Pwd=;");
//select data from db
$grower = "SELECT DISTINCT farmer FROM INSCALE";
$cows = $db->query($grower);
//end
echo "<select name='term'>";
echo '<option selected disabled value="">Select Farmer...</option>';
while ($row = $cows->fetch()) {
echo "<option value='" . $row['farmer'] . "' >" . $row['farmer'] . "</option>";
}
echo "</select>";

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

513
lasuca/farmdata/index.php Normal file
View File

@@ -0,0 +1,513 @@
<?php
// phpcs:ignoreFile
if (!function_exists('sqlsrv_query')) {
define('FARMDATA_SQLSRV_STUB', true);
function sqlsrv_query($conn, $sql, $params = array(), $options = array())
{
return false;
}
function sqlsrv_fetch_array($stmt, $fetchType)
{
return false;
}
function sqlsrv_free_stmt($stmt)
{
return false;
}
function sqlsrv_connect($serverName, $connectionInfo)
{
return false;
}
function sqlsrv_close($conn)
{
return true;
}
}
function farmdata_env($key, $fallback = null)
{
$value = getenv($key);
if ($value === false || $value === null || $value === '') {
return $fallback;
}
return $value;
}
function farmdata_fetch_column($conn, $sql, $params = array())
{
$results = array();
if (!function_exists('sqlsrv_query')) {
return $results;
}
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
return $results;
}
$fetchNumeric = defined('SQLSRV_FETCH_NUMERIC') ? constant('SQLSRV_FETCH_NUMERIC') : 2;
while ($row = sqlsrv_fetch_array($stmt, $fetchNumeric)) {
if (!isset($row[0])) {
continue;
}
$value = trim((string) $row[0]);
if ($value === '') {
continue;
}
$results[] = $value;
}
if (function_exists('sqlsrv_free_stmt')) {
sqlsrv_free_stmt($stmt);
}
return $results;
}
function farmdata_format_number($value, $decimals = 0)
{
if (!is_numeric($value)) {
return '—';
}
return number_format((float) $value, $decimals);
}
function farmdata_h($value)
{
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
$filters = array(
'grower' => isset($_GET['grower']) ? trim((string) $_GET['grower']) : '',
'cropday' => isset($_GET['cropday']) ? trim((string) $_GET['cropday']) : '',
'vehicle' => isset($_GET['vehicle']) ? trim((string) $_GET['vehicle']) : '',
'tract' => isset($_GET['tract']) ? trim((string) $_GET['tract']) : '',
'load' => isset($_GET['load']) ? trim((string) $_GET['load']) : '',
'overload' => isset($_GET['overload']) && $_GET['overload'] === '1',
);
$serverName = farmdata_env('SQLSRV_HOST', 'CBM2K12\\SQLEXPRESS');
$connectionInfo = array(
'UID' => farmdata_env('SQLSRV_USERNAME', 'cbmclient'),
'PWD' => farmdata_env('SQLSRV_PASSWORD', 'ascbm2k'),
'ReturnDatesAsStrings' => true,
'CharacterSet' => 'UTF-8',
'Database' => farmdata_env('SQLSRV_DATABASE', 'SugarCaneScale'),
);
$conn = null;
$connectionError = null;
$growerOptions = array();
$cropDayOptions = array();
$vehicleSuggestions = array();
$tractSuggestions = array();
$loadSuggestions = array();
$latestCropDay = null;
$latestCropDayTons = null;
$overallTons = null;
$rows = array();
$resultTotals = array(
'tons' => 0.0,
'gross' => 0.0,
'tare' => 0.0,
);
if (defined('FARMDATA_SQLSRV_STUB') || !function_exists('sqlsrv_connect')) {
$connectionError = 'The SQL Server driver is not available on this server.';
} else {
$conn = @sqlsrv_connect($serverName, $connectionInfo);
if ($conn === false) {
$connectionError = 'Unable to connect to the load data database at this time.';
} else {
$growerOptions = farmdata_fetch_column(
$conn,
"SELECT DISTINCT AccountName FROM Tract WHERE AccountName IS NOT NULL AND AccountName <> '' ORDER BY AccountName ASC"
);
$cropDayOptions = farmdata_fetch_column(
$conn,
"SELECT DISTINCT CropDay FROM LoadData WHERE CropDay IS NOT NULL ORDER BY CropDay DESC"
);
$vehicleSuggestions = farmdata_fetch_column(
$conn,
"SELECT DISTINCT TOP 75 VehicleId_Fk FROM LoadData WHERE VehicleId_Fk IS NOT NULL AND VehicleId_Fk <> '' ORDER BY VehicleId_Fk ASC"
);
$tractSuggestions = farmdata_fetch_column(
$conn,
"SELECT DISTINCT TOP 75 TractId_Fk FROM LoadData WHERE TractId_Fk IS NOT NULL AND TractId_Fk <> '' ORDER BY TractId_Fk ASC"
);
$loadSuggestions = farmdata_fetch_column(
$conn,
"SELECT DISTINCT TOP 50 LoadId_Pk FROM LoadData WHERE LoadId_Pk IS NOT NULL ORDER BY LoadId_Pk DESC"
);
$latestStmt = sqlsrv_query(
$conn,
'SELECT TOP 1 CropDay, SUM(Tons) AS total_tons FROM LoadData WHERE CropDay IS NOT NULL GROUP BY CropDay ORDER BY CropDay DESC'
);
if ($latestStmt !== false) {
$fetchAssoc = defined('SQLSRV_FETCH_ASSOC') ? constant('SQLSRV_FETCH_ASSOC') : 2;
$latestRow = sqlsrv_fetch_array($latestStmt, $fetchAssoc);
if ($latestRow) {
$latestCropDay = $latestRow['CropDay'];
$latestCropDayTons = isset($latestRow['total_tons']) ? (float) $latestRow['total_tons'] : null;
}
if (function_exists('sqlsrv_free_stmt')) {
sqlsrv_free_stmt($latestStmt);
}
}
$overallStmt = sqlsrv_query(
$conn,
'SELECT SUM(Tons) AS total_tons FROM LoadData'
);
if ($overallStmt !== false) {
$fetchAssoc = isset($fetchAssoc) ? $fetchAssoc : (defined('SQLSRV_FETCH_ASSOC') ? constant('SQLSRV_FETCH_ASSOC') : 2);
$overallRow = sqlsrv_fetch_array($overallStmt, $fetchAssoc);
if ($overallRow && isset($overallRow['total_tons'])) {
$overallTons = (float) $overallRow['total_tons'];
}
if (function_exists('sqlsrv_free_stmt')) {
sqlsrv_free_stmt($overallStmt);
}
}
$query = "SELECT TOP 500
ld.LoadId_Pk,
ld.CropDay,
ld.VehicleId_Fk,
ld.TractId_Fk,
ld.TareWt,
ld.GrossWt,
ld.Tons,
ld.FarmerId_Fk,
CONVERT(varchar(20), ld.DateOut, 100) AS TimeOutFormatted,
ld.Parked,
t.AccountName
FROM LoadData ld
LEFT JOIN (
SELECT AccountId_Pk, MAX(AccountName) AS AccountName
FROM Tract
WHERE AccountName IS NOT NULL AND AccountName <> ''
GROUP BY AccountId_Pk
) t ON ld.FarmerId_Fk = t.AccountId_Pk";
$conditions = array();
$params = array();
if ($filters['grower'] !== '') {
$conditions[] = 't.AccountName = ?';
$params[] = $filters['grower'];
}
if ($filters['cropday'] !== '') {
$conditions[] = 'ld.CropDay = ?';
$params[] = $filters['cropday'];
}
if ($filters['vehicle'] !== '') {
$conditions[] = 'ld.VehicleId_Fk LIKE ?';
$params[] = $filters['vehicle'] . '%';
}
if ($filters['tract'] !== '') {
$conditions[] = 'ld.TractId_Fk LIKE ?';
$params[] = $filters['tract'] . '%';
}
if ($filters['load'] !== '') {
$conditions[] = 'ld.LoadId_Pk = ?';
$params[] = (int) $filters['load'];
}
if ($filters['overload']) {
$conditions[] = 'ld.GrossWt >= ?';
$params[] = 100000;
}
if (!empty($conditions)) {
$query .= ' WHERE ' . implode(' AND ', $conditions);
}
$query .= ' ORDER BY ld.DateOut DESC, ld.LoadId_Pk DESC';
$cursorType = defined('SQLSRV_CURSOR_KEYSET') ? constant('SQLSRV_CURSOR_KEYSET') : 1;
$loadStmt = sqlsrv_query($conn, $query, $params, array('Scrollable' => $cursorType));
if ($loadStmt === false) {
$connectionError = 'Unable to retrieve load data right now.';
} else {
$fetchAssoc = defined('SQLSRV_FETCH_ASSOC') ? constant('SQLSRV_FETCH_ASSOC') : 2;
while ($row = sqlsrv_fetch_array($loadStmt, $fetchAssoc)) {
$tons = isset($row['Tons']) && is_numeric($row['Tons']) ? (float) $row['Tons'] : null;
$tare = isset($row['TareWt']) && is_numeric($row['TareWt']) ? (float) $row['TareWt'] : null;
$gross = isset($row['GrossWt']) && is_numeric($row['GrossWt']) ? (float) $row['GrossWt'] : null;
$parkedRaw = isset($row['Parked']) ? trim((string) $row['Parked']) : '';
$parked = in_array(strtoupper($parkedRaw), array('1', 'Y', 'YES', 'TRUE'), true);
if ($tons !== null) {
$resultTotals['tons'] += $tons;
}
if ($tare !== null) {
$resultTotals['tare'] += $tare;
}
if ($gross !== null) {
$resultTotals['gross'] += $gross;
}
$rows[] = array(
'load_id' => isset($row['LoadId_Pk']) ? (int) $row['LoadId_Pk'] : null,
'crop_day' => isset($row['CropDay']) ? $row['CropDay'] : '',
'vehicle' => isset($row['VehicleId_Fk']) ? trim((string) $row['VehicleId_Fk']) : '',
'tract' => isset($row['TractId_Fk']) ? trim((string) $row['TractId_Fk']) : '',
'grower' => isset($row['AccountName']) ? trim((string) $row['AccountName']) : '',
'tons' => $tons,
'tare' => $tare,
'gross' => $gross,
'time_out' => isset($row['TimeOutFormatted']) ? trim((string) $row['TimeOutFormatted']) : '',
'parked' => $parked,
);
}
if (function_exists('sqlsrv_free_stmt')) {
sqlsrv_free_stmt($loadStmt);
}
}
if (function_exists('sqlsrv_close')) {
sqlsrv_close($conn);
}
}
}
$resultCount = count($rows);
$pageTitle = 'Load Data Explorer';
$metaDescription = 'Search LASUCA load data by grower, crop day, vehicle, or tract.';
$activeNav = 'production';
$extraStyles = array('/new/css/farmdata.css');
$extraScripts = array('/new/js/scripts.js');
$rootDir = __DIR__;
require $rootDir . '/../inc/theme-header.php';
?>
<main>
<header class="hero hero-sub farmdata-hero">
<div class="container">
<span class="badge">Live load data</span>
<h1 class="mt-3">Search cane deliveries and scale tickets.</h1>
<p class="lead">
Filter the latest loads by grower, crop day, vehicle, or tract. Results update instantly and include live
tonnage, tare, and gross weight totals so you can track activity at a glance.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<?php if ($connectionError !== null): ?>
<div class="alert alert-warning" role="alert">
<?php echo farmdata_h($connectionError); ?>
</div>
<?php endif; ?>
<div class="farmdata-search-card">
<form method="get" action="index.php" class="row g-4 align-items-end">
<div class="col-12 col-md-6 col-xl-3">
<label for="grower" class="form-label">Grower</label>
<select class="form-select" id="grower" name="grower">
<option value="">All growers</option>
<?php foreach ($growerOptions as $option): ?>
<option value="<?php echo farmdata_h($option); ?>"<?php echo $filters['grower'] === $option ? ' selected' : ''; ?>>
<?php echo farmdata_h($option); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12 col-md-6 col-xl-3">
<label for="cropday" class="form-label">Crop day</label>
<select class="form-select" id="cropday" name="cropday">
<option value="">All crop days</option>
<?php foreach ($cropDayOptions as $option): ?>
<option value="<?php echo farmdata_h($option); ?>"<?php echo $filters['cropday'] === $option ? ' selected' : ''; ?>>
<?php echo farmdata_h($option); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12 col-md-6 col-xl-3">
<label for="vehicle" class="form-label">Vehicle</label>
<input
type="text"
class="form-control"
id="vehicle"
name="vehicle"
list="vehicleOptions"
value="<?php echo farmdata_h($filters['vehicle']); ?>"
placeholder="e.g. V9901"
/>
<datalist id="vehicleOptions">
<?php foreach ($vehicleSuggestions as $option): ?>
<option value="<?php echo farmdata_h($option); ?>"></option>
<?php endforeach; ?>
</datalist>
</div>
<div class="col-12 col-md-6 col-xl-3">
<label for="tract" class="form-label">Tract</label>
<input
type="text"
class="form-control"
id="tract"
name="tract"
list="tractOptions"
value="<?php echo farmdata_h($filters['tract']); ?>"
placeholder="Tract ID"
/>
<datalist id="tractOptions">
<?php foreach ($tractSuggestions as $option): ?>
<option value="<?php echo farmdata_h($option); ?>"></option>
<?php endforeach; ?>
</datalist>
</div>
<div class="col-12 col-md-6 col-xl-3">
<label for="load" class="form-label">Load #</label>
<input
type="number"
class="form-control"
id="load"
name="load"
list="loadOptions"
value="<?php echo farmdata_h($filters['load']); ?>"
placeholder="Exact load number"
min="1"
/>
<datalist id="loadOptions">
<?php foreach ($loadSuggestions as $option): ?>
<option value="<?php echo farmdata_h($option); ?>"></option>
<?php endforeach; ?>
</datalist>
</div>
<div class="col-12 col-md-6 col-xl-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="1" id="overload" name="overload"<?php echo $filters['overload'] ? ' checked' : ''; ?> />
<label class="form-check-label" for="overload">Show overloads (gross ≥ 100,000)</label>
</div>
</div>
<div class="col-12 col-md-6 col-xl-3 ms-auto">
<button type="submit" class="btn btn-success w-100">Search loads</button>
</div>
<div class="col-12 col-md-6 col-xl-3">
<a class="btn btn-outline-secondary w-100" href="/farmdata/index.php">Reset filters</a>
</div>
</form>
</div>
<div class="farmdata-metrics">
<div class="farmdata-metric">
<h4>Loads returned</h4>
<p><?php echo farmdata_h(number_format($resultCount)); ?> matching records</p>
</div>
<div class="farmdata-metric">
<h4>Result tons</h4>
<p><?php echo farmdata_h(farmdata_format_number($resultTotals['tons'], 2)); ?> total tons</p>
</div>
<div class="farmdata-metric">
<h4>Latest crop day</h4>
<p>
<?php if ($latestCropDay !== null): ?>
Day <?php echo farmdata_h($latestCropDay); ?> · <?php echo farmdata_h(farmdata_format_number($latestCropDayTons, 2)); ?> tons
<?php else: ?>
Not available
<?php endif; ?>
</p>
</div>
<div class="farmdata-metric">
<h4>All-time tons</h4>
<p><?php echo farmdata_h(farmdata_format_number($overallTons, 2)); ?> tons processed</p>
</div>
</div>
<div class="farmdata-results-card">
<?php if ($resultCount === 0): ?>
<p class="mb-0 text-muted">No loads match the filters you selected. Try adjusting the search criteria.</p>
<?php else: ?>
<div class="farmdata-results-summary">
<span>Gross: <?php echo farmdata_h(farmdata_format_number($resultTotals['gross'], 0)); ?></span>
<span>Tare: <?php echo farmdata_h(farmdata_format_number($resultTotals['tare'], 0)); ?></span>
<span>Tons: <?php echo farmdata_h(farmdata_format_number($resultTotals['tons'], 2)); ?></span>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th scope="col">Load #</th>
<th scope="col">Crop day</th>
<th scope="col">Grower</th>
<th scope="col">Tract</th>
<th scope="col">Vehicle</th>
<th scope="col">Gross</th>
<th scope="col">Tare</th>
<th scope="col">Tons</th>
<th scope="col">Time out</th>
<th scope="col">Parked</th>
</tr>
</thead>
<tbody>
<?php foreach ($rows as $row): ?>
<tr>
<td><?php echo farmdata_h($row['load_id']); ?></td>
<td><?php echo farmdata_h($row['crop_day']); ?></td>
<td><?php echo $row['grower'] !== '' ? farmdata_h($row['grower']) : '—'; ?></td>
<td><?php echo $row['tract'] !== '' ? farmdata_h($row['tract']) : '—'; ?></td>
<td><?php echo $row['vehicle'] !== '' ? farmdata_h($row['vehicle']) : '—'; ?></td>
<td><?php echo farmdata_h(farmdata_format_number($row['gross'], 0)); ?></td>
<td><?php echo farmdata_h(farmdata_format_number($row['tare'], 0)); ?></td>
<td><?php echo farmdata_h(farmdata_format_number($row['tons'], 2)); ?></td>
<td><?php echo $row['time_out'] !== '' ? farmdata_h($row['time_out']) : '—'; ?></td>
<td><?php echo $row['parked'] ? '<span class="badge bg-warning text-dark">Yes</span>' : '<span class="badge bg-success">No</span>'; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</section>
</main>
<?php require $rootDir . '/../inc/theme-footer.php'; ?>

View File

@@ -0,0 +1,135 @@
<!DOCTYPE html>
<html>
<head>
<title>Load Data</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
</head>
<body>
<div class="center">
<div class="header">
</div>
<div class="row">
<div class="col-3 right">
<div class="aside">
<?php include("tonsin.php");?>
<?php include("tonsintot.php");?>
</div>
</div>
<?php
$dbName = "G:\CBM\SC\data\D_SCALE.mdb";
if (!file_exists($dbName)) {
die("Could not find database file.");
}
$db = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$dbName; Uid=; Pwd=;");
//select data from db
$sql = "SELECT `Load Data`.`Load No`,
`Load Data`.`Crop Day`,
`Load Data`.`Tract No`,
`Load Data`.`Gross Wt`,
`Load Data`.`In Tare`,
`Load Data`.Tons,
`Load Data`.`In Time`,
`Load Data`.`Out Time`,
INSCALE.farmer,
INSCALE.REMTONs,
INSCALE.hauled
FROM `Load Data` RIGHT JOIN INSCALE ON `Load Data`.`Load No` = INSCALE.Load
WHERE `Crop Day` = ( SELECT Max(`Crop Day`)FROM `Load Data`)
ORDER BY `Crop Day`, `Load No` DESC";
$result = $db->query($sql);
$tonsin = 0;
$tonsin2 = 0;
?>
<div class="col-6">
<table style="margin: 0px auto;">
<tr>
<th>
<form action="search.php">
<?php include("dayselect.php");?>
<?php include("growerselect.php");?><br>
<input id="option" type="checkbox" name="over" value="100000">
<label for="option"><span></span>OVERLOAD</label>
<input type="submit" value="Search" />
</form>
</th>
</tr>
</table>
<table style="margin: 0px auto;" class="stat">
<tr>
<th>Live Scale Load Data</th>
</tr>
</table>
<table class="stat">
<thead>
<tr>
<th>Load</th>
<th>Day</th>
<th>Tract</th>
<th>Grower</th>
<th>Gross</th>
<th>Tare</th>
<th>Tons</th>
<th>Hauled</th>
<th>Remaining</th>
</tr>
</thead>
<?php
while ($row = $result->fetch())
{
echo "<tr>";
echo "<td>".$row [ 'Load No' ]."</td>";
echo "<td><b>".$row [ 'Crop Day' ]."</b></td>";
echo "<td>".$row [ 'Tract No' ]."</td>";
echo "<td>".$row [ 'farmer' ]."</td>";
echo "<td>".$row [ 'Gross Wt' ]." </td>";
echo "<td>".$row [ 'In Tare' ]." </td>";
echo "<td>".$row [ 'Tons' ]."</td>";
echo "<td>".$row [ 'hauled' ]." Tons</td>";
echo "<td>".$row [ 'REMTONs' ]." Tons</td>";
echo "</tr>";
}
//end
?>
</table>
</div>
<a href="#" class="back-to-top">Back to Top</a>
</div>
<?php include 'footer.php';?>
<script type="text/javascript">
// create the back to top button
$('body').prepend('<a href="#" class="back-to-top">Back to Top</a>');
var amountScrolled = 300;
$(window).scroll(function() {
if ($(window).scrollTop() > amountScrolled) {
$('a.back-to-top').fadeIn('slow');
} else {
$('a.back-to-top').fadeOut('slow');
}
});
$('a.back-to-top, a.simple-back-to-top').click(function() {
$('body').animate({
scrollTop: 0
}, 'fast');
return false;
});
</script>
</body>
</html>

151
lasuca/farmdata/indextest Normal file
View File

@@ -0,0 +1,151 @@
<!DOCTYPE html>
<html>
<head>
<title>Load Data</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
</head>
<body>
<div class="center">
<div class="header">
</div>
<div class="row">
<div class="col-3 right">
<div class="aside">
<?php include("tonsin.php");?>
<?php include("tonsintot.php");?>
</div>
</div>
<div class="col-6">
<?php
if(isset($_GET['submit'])){
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
//select data from db
$sql = "SELECT LoadData.LoadId_Pk,
LoadData.CropDay,
LoadData.VehicleId_Fk,
LoadData.TractId_Fk,
LoadData.TareWt,
LoadData.GrossWt,
LoadData.Tons,
LoadData.FarmerId_Fk,
CONVERT(varchar, LoadData.DateOut, 100) [TIME],
LoadData.Parked,
Tract.AccountName
FROM LoadData RIGHT JOIN Tract ON LoadData.FarmerId_Fk = Tract.AccountId_Pk
GROUP BY LoadData.LoadId_Pk,
LoadData.CropDay,
LoadData.VehicleId_Fk,
LoadData.TractId_Fk,
LoadData.TareWt,
LoadData.GrossWt,
LoadData.Tons,
LoadData.FarmerId_Fk,
LoadData.DateOut,
LoadData.Parked,
Tract.AccountName
ORDER by LoadId_Pk DESC";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
$tonsin = 0;
$tonsin2 = 0;
}
?>
<table style="margin: 0px auto;" class="stat">
<tr>
<th>Live Scale Load Data</th>
</tr>
</table>
<table class="stat">
<thead>
<tr>
<th>Load</th>
<th>Day</th>
<th>Tract</th>
<th>Grower</th>
<th>Gross</th>
<th>Tare</th>
<th>Tons</th>
<th>Out Time</th>
</tr>
</thead>
<?php
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$tonsin += $row['Tons'];
echo "<tr>";
echo "<td>".$row ['LoadId_Pk']."</td>";
echo "<td><b>".$row ['CropDay']."</b></td>";
echo "<td>".$row ['TractId_Fk']."</td>";
echo "<td>".$row ['AccountName']."</td>";
echo "<td>".$row ['GrossWt']." </td>";
echo "<td>".$row ['TareWt']." </td>";
echo "<td>".$row ['Tons']." </td>";
echo "<td>".$row ['TIME']." </td>";
echo "</tr>";
}
//end
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>
</table>
<table style="margin: 0px auto;">
<tr>
<th id="vtitle" id="padded">Total Tons:</th>
<th align="right" id="sum-count"><?php echo $tonsin; ?></th>
</tr>
</table>
</div>
<a href="#" class="back-to-top">Back to Top</a>
</div>
<?php include 'footer.php';?>
<script type="text/javascript">
// create the back to top button
$('body').prepend('<a href="#" class="back-to-top">Back to Top</a>');
var amountScrolled = 300;
$(window).scroll(function() {
if ($(window).scrollTop() > amountScrolled) {
$('a.back-to-top').fadeIn('slow');
} else {
$('a.back-to-top').fadeOut('slow');
}
});
$('a.back-to-top, a.simple-back-to-top').click(function() {
$('body').animate({
scrollTop: 0
}, 'fast');
return false;
});
</script>
</body>
</html>

View File

@@ -0,0 +1,54 @@
<?php
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
$sql = "SELECT VehicleId_Fk, LoadId_Pk, CropDay, TractId_Fk, TareWt, GrossWt, Tons, FarmerId_Fk, CONVERT(varchar, DateOut, 100) [TIME], SplitPercent, Parked
FROM LoadData
WHERE VehicleId_Fk
LIKE 'V99%'
ORDER by LoadId_Pk DESC";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
?>
<table width="100%">
<thead>
<tr>
<th>Load No</th>
<th>Vehicle</th>
<th>Tract</th>
<th>Tons</th>
<th>Tare</th>
<th>Gross</th>
<th>Time Out</th>
</tr>
</thead>
<?php
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
echo "<tr>";
echo"<td>".$row['LoadId_Pk']."</td>";
echo"<td>".$row['VehicleId_Fk']."</td>";
echo"<td>".$row['TractId_Fk']."</td>";
echo"<td>".$row['Tons']."</td>";
echo"<td>".$row['TareWt']."</td> ";
echo"<td>".$row['GrossWt']."</td> ";
echo "</tr>";
}
/* Free statement and connection resources. */
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>
</table>

9
lasuca/farmdata/menu.php Normal file
View File

@@ -0,0 +1,9 @@
<div class="col-3 menu">
<ul>
<li>Factory info</li>
<li>Production</li>
<li>Grower Login</li>
<li>Contact & Personnel</li>
</ul>
</div>

View File

@@ -0,0 +1,34 @@
<?php
$serverName = "LASUCA2K8\CBM";
$uid = "cbm";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
$sql = "SELECT TOP 20 LoadId_Pk, CropDay, TractId_Fk, TareIN, GrossWt, Tons, FarmerId_Fk, DateOut, SplitPercent
FROM LoadData
WHERE FarmerId_Fk
LIKE 32002
ORDER by LoadId_Pk DESC";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
echo $row['LoadId_Pk'].", ".$row['TareIN'].", ".$row['GrossWt'].", ".$row['Tons'].", ".$row['GrossWt'].", ".$row['FarmerId_Fk']."<br />";
}
/* Free statement and connection resources. */
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>

158
lasuca/farmdata/report.php Normal file
View File

@@ -0,0 +1,158 @@
<!DOCTYPE html>
<html>
<head>
<title>Load Data</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
</head>
<body>
<div class="center">
<div class="header">
</div>
<div class="row">
<div class="col-3 right">
<div class="aside">
<?php include("tonsin.php");?>
<?php include("tonsintot.php");?>
</div>
</div>
<div class="col-6">
<table style="margin: 0px auto;">
<tr>
<th>
<form method="POST" action="search.php">
<?php include("dayselect.php");?>
<?php include("growerselect.php");?><br>
<input id="option" type="checkbox" name="over" value="100000">
<label for="option"><span></span>OVERLOADS</label>
<input type="submit" value="Search" />
</form>
</th>
</tr>
</table>
<?php
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
//select data from db
$sql = "SELECT LoadData.LoadId_Pk,
LoadData.CropDay,
LoadData.TractId_Fk,
LoadData.TareWt,
LoadData.GrossWt,
LoadData.Tons,
LoadData.FarmerId_Fk,
CONVERT(varchar, LoadData.DateOut, 100) [TIME],
LoadData.Parked,
Tract.AccountName
FROM LoadData RIGHT JOIN Tract ON LoadData.FarmerId_Fk = Tract.AccountId_Pk
WHERE CropDay = 90
GROUP BY LoadData.LoadId_Pk,
LoadData.CropDay,
LoadData.TractId_Fk,
LoadData.TareWt,
LoadData.GrossWt,
LoadData.Tons,
LoadData.FarmerId_Fk,
LoadData.DateOut,
LoadData.Parked,
Tract.AccountName
ORDER by LoadId_Pk DESC";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
$tonsin = 0;
$tonsin2 = 0;
?>
<table style="margin: 0px auto;" class="stat">
<tr>
<th>Live Scale Load Data</th>
</tr>
</table>
<table class="stat">
<thead>
<tr>
<th>Load</th>
<th>Day</th>
<th>Tract</th>
<th>Grower</th>
<th>Gross</th>
<th>Tare</th>
<th>Tons</th>
<th>Out Time</th>
</tr>
</thead>
<?php
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$tonsin += $row['Tons'];
echo "<tr>";
echo "<td>".$row ['LoadId_Pk']."</td>";
echo "<td><b>".$row ['CropDay']."</b></td>";
echo "<td>".$row ['TractId_Fk']."</td>";
echo "<td>".$row ['AccountName']."</td>";
echo "<td>".$row ['GrossWt']." </td>";
echo "<td>".$row ['TareWt']." </td>";
echo "<td>".$row ['Tons']." </td>";
echo "<td>".$row ['TIME']." </td>";
echo "</tr>";
}
//end
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>
</table>
<table style="margin: 0px auto;">
<tr>
<th id="vtitle" id="padded">Total Tons:</th>
<th align="right" id="sum-count"><?php echo $tonsin; ?></th>
</tr>
</table>
</div>
<a href="#" class="back-to-top">Back to Top</a>
</div>
<?php include 'footer.php';?>
<script type="text/javascript">
// create the back to top button
$('body').prepend('<a href="#" class="back-to-top">Back to Top</a>');
var amountScrolled = 300;
$(window).scroll(function() {
if ($(window).scrollTop() > amountScrolled) {
$('a.back-to-top').fadeIn('slow');
} else {
$('a.back-to-top').fadeOut('slow');
}
});
$('a.back-to-top, a.simple-back-to-top').click(function() {
$('body').animate({
scrollTop: 0
}, 'fast');
return false;
});
</script>
</body>
</html>

163
lasuca/farmdata/search.php Normal file
View File

@@ -0,0 +1,163 @@
<!DOCTYPE html>
<html>
<head>
<title>Load Data</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
</head>
<body>
<div class="center">
<div class="header">
</div>
<div class="row">
<div class="col-3 right">
<div class="aside">
<?php include("tonsin.php");?>
<?php include("tonsintot.php");?>
</div>
</div>
<div class="col-6">
<table style="margin: 0px auto;">
<tr>
<th>
<form action="index.php">
<?php include("dayselect.php");?>
<?php include("growerselect.php");?><br>
<input id="option" type="checkbox" name="over" value="100000">
<label for="option"><span></span>OVERLOADS</label>
<input type="submit" value="Reset Search" />
</form>
</th>
</tr>
</table>
<?php
print_r($_POST);
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
//select data from db
$grower = $_POST['grower'];
$cropday = $_POST['cropday'];
$sql = "SELECT LoadData.LoadId_Pk,
LoadData.CropDay,
LoadData.TractId_Fk,
LoadData.TareWt,
LoadData.GrossWt,
LoadData.Tons,
LoadData.FarmerId_Fk,
CONVERT(varchar, LoadData.DateOut, 100) [TIME],
LoadData.Parked,
Tract.AccountName
FROM LoadData RIGHT JOIN Tract ON LoadData.FarmerId_Fk = Tract.AccountName
WHERE CropDay LIKE '%".$cropday."%' OR AccountName LIKE '%".$grower."%'
GROUP BY LoadData.LoadId_Pk,
LoadData.CropDay,
LoadData.TractId_Fk,
LoadData.TareWt,
LoadData.GrossWt,
LoadData.Tons,
LoadData.FarmerId_Fk,
LoadData.DateOut,
LoadData.Parked,
Tract.AccountName
ORDER by LoadId_Pk DESC";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
$tonsin = 0;
$tonsin2 = 0;
?>
<table style="margin: 0px auto;" class="stat">
<tr>
<th>Live Scale Load Data</th>
</tr>
</table>
<table class="stat">
<thead>
<tr>
<th>Load</th>
<th>Day</th>
<th>Tract</th>
<th>Grower</th>
<th>Gross</th>
<th>Tare</th>
<th>Tons</th>
<th>Out Time</th>
</tr>
</thead>
<?php
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$tonsin += $row['Tons'];
echo "<tr>";
echo "<td>".$row ['LoadId_Pk']."</td>";
echo "<td><b>".$row ['CropDay']."</b></td>";
echo "<td>".$row ['TractId_Fk']."</td>";
echo "<td>".$row ['AccountName']."</td>";
echo "<td>".$row ['GrossWt']." </td>";
echo "<td>".$row ['TareWt']." </td>";
echo "<td>".$row ['Tons']." </td>";
echo "<td>".$row ['TIME']." </td>";
echo "</tr>";
}
//end
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn);
?>
</table>
</div>
<a href="#" class="back-to-top">Back to Top</a>
</div>
<?php include 'footer.php';?>
<script type="text/javascript">
// create the back to top button
$('body').prepend('<a href="#" class="back-to-top">Back to Top</a>');
var amountScrolled = 300;
$(window).scroll(function() {
if ($(window).scrollTop() > amountScrolled) {
$('a.back-to-top').fadeIn('slow');
} else {
$('a.back-to-top').fadeOut('slow');
}
});
$('a.back-to-top, a.simple-back-to-top').click(function() {
$('body').animate({
scrollTop: 0
}, 'fast');
return false;
});
</script>
</body>
</html>

232
lasuca/farmdata/style.css Normal file
View File

@@ -0,0 +1,232 @@
body{
max-width: 1080px;
margin: 0 auto !important;
float: none !important;
background-image: url("images/bg.gif");
background-color: #000;
}
* {
box-sizing: border-box;
}
.center {
background-color: #fff;
}
.row:after {
content: "";
clear: both;
display: block;
}
[class*="col-"] {
float: left;
padding: 15px;
}
html, html a {
font-family: Arial, "Lucida Sans", sans-serif;
-webkit-font-smoothing: antialiased !important;
text-shadow: 1px 1px 1px rgba(0,0,0,0.004);
}
.header {
background-image: url("images/fulllogo.png");
background-repeat: no-repeat;
background-position: center;
background-color: #474719;
height: 100px;
color: #ffffff;
padding: 15px;
}
h1 {
padding: 0px;
margin: 0px;
}
p{
padding: 0px;
margin: 0px;
}
.menu ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.menu li {
padding: 8px;
margin-bottom: 7px;
background-color :#333300;
color: #ffffff;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}
.menu li:hover {
background-color: #333333;
}
.aside {
background-color: #474719;
padding: 2px;
color: #ffffff;
text-align: center;
font-size: 14px;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}
.footer {
background-color: #474719;
color: #ffffff;
text-align: center;
font-size: 12px;
padding: 15px;
}
/* For desktop: */
.col-1 {width: 8.33%;}
.col-2 {width: 16.66%;}
.col-3 {width: 20%;}
.col-4 {width: 33.33%;}
.col-5 {width: 41.66%;}
.col-6 {width: 80%;}
.col-7 {width: 58.33%;}
.col-8 {width: 66.66%;}
.col-9 {width: 75%;}
.col-10 {width: 83.33%;}
.col-11 {width: 91.66%;}
.col-12 {width: 100%;}
/*
Max width before this PARTICULAR table gets nasty
This query will take effect for any screen smaller than 760px
and also iPads specifically.
*/
@media
only screen and (max-width: 760px),
(min-device-width: 768px) and (max-device-width: 1024px) {
/* For mobile phones: */
[class*="col-"] {
width: 100%;
}
/* Force table to not be like tables anymore */
table, thead, tbody, th, td, tr {
display: block;
}
/* Hide table headers (but not display: none;, for accessibility) */
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
tr { border: 1px solid #ccc; }
td {
/* Behave like a "row" */
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
}
td:before {
/* Now like a table header */
position: absolute;
/* Top/left values mimic padding */
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
/*
Label the data
*/
td:nth-of-type(1):before { content: "Load Number"; }
td:nth-of-type(2):before { content: "Vehicle ID"; }
td:nth-of-type(3):before { content: "Tract No"; }
td:nth-of-type(4):before { content: "Tons"; }
td:nth-of-type(5):before { content: "Gross Wt"; }
td:nth-of-type(6):before { content: "Tare Wt"; }
td:nth-of-type(7):before { content: "Time Out"; }
td:nth-of-type(8):before { content: "Tons Hauled"; }
td:nth-of-type(9):before { content: "Tons Remaining"; }
}
table {
border-collapse: collapse;
width: 100%;
}
table, th, td {
border: 1px solid black;
}
th {
background-color: grey;
color: white;
text-align: center;
vertical-align: center;
}
td {
text-align: center;
}
tr:nth-child(even) {
background: #6C6C47;
color: white;
}
tr:nth-child(odd) {
background: #FFF;
color: black;
}
input[type=checkbox]:not(old),
input[type=radio ]:not(old){aa
width : 2em;
margin : 0;
padding : 0;
font-size : 1em;
opacity : 0;
}
input[type=checkbox]:not(old) + label,
input[type=radio ]:not(old) + label{
display : inline-block;
margin-left : -2em;
line-height : 1.5em;
}
input[type=checkbox]:not(old) + label > span,
input[type=radio ]:not(old) + label > span{
display : inline-block;
width : 0.875em;
height : 0.875em;
margin : 0.05em 0.2em 0.35em 0.9em;
border : 0.0625em solid rgb(192,192,192);
border-radius : 0.25em;
background : rgb(224,224,224);
background-image : -moz-linear-gradient(rgb(240,240,240),rgb(224,224,224));
background-image : -ms-linear-gradient(rgb(240,240,240),rgb(224,224,224));
background-image : -o-linear-gradient(rgb(240,240,240),rgb(224,224,224));
background-image : -webkit-linear-gradient(rgb(240,240,240),rgb(224,224,224));
background-image : linear-gradient(rgb(240,240,240),rgb(224,224,224));
vertical-align : bottom;
}
input[type=checkbox]:not(old):checked + label > span:before{
content : '✓';
display : block;
width : 1em;
color : rgb(153,204,102);
font-size : 0.875em;
line-height : 1em;
text-align : center;
text-shadow : 0 0 0.0714em rgb(115,153,77);
font-weight : bold;
}
a.back-to-top {
display: none;
width: 35px;
height: 35px;
text-indent: -9999px;
position: fixed;
z-index: 999;
right: 20px;
bottom: 20px;
background: #27AE61 url("up-arrow.png") no-repeat center 43%;
-webkit-border-radius: 30px;
-moz-border-radius: 30px;
border-radius: 30px;
}
a:hover.back-to-top {
background-color: #000;
}

47
lasuca/farmdata/test.php Normal file
View File

@@ -0,0 +1,47 @@
<?php
//New Join Query
$sql = "SELECT `Load Data`.`Load No`,
`Load Data`.`Crop Day`,
`Load Data`.`Tract No`,
`Load Data`.`Gross Wt`,
`Load Data`.`In Tare`,
`Load Data`.Tons,
`Load Data`.`In Time`,
`Load Data`.`Out Time`,
INSCALE.Hauler
FROM `Load Data` RIGHT JOIN INSCALE ON `Load Data`.`Load No` = INSCALE.Load ORDER BY `Crop Day` DESC,`In Time` DESC";
{
echo "<tr>";
echo "<td>".$row [ 'load' ]."</td>";
echo "<td>".$row [ 'cropday' ]."</td>";
echo "<td>".$row [ 'tractno' ]."</td>";
echo "<td>".$row [ 'gross' ]." </td>";
echo "<td>".$row [ 'intare' ]." </td>";
echo "<td>".$row [ 'tons' ]." Tons</td>";
echo "<td>".$row [ 'intime' ]." </td>";
echo "<td>".$row [ 'outtime' ]." </td>";
echo "</tr>";
}
//Original Query
$sql = "SELECT * FROM `Load Data` ORDER BY `Crop Day` DESC,`In Time` DESC";
{
echo "<tr>";
echo "<td>".$row [ 'Load No' ]."</td>";
echo "<td>".$row [ 'Crop Day' ]."</td>";
echo "<td>".$row [ 'Tract No' ]."</td>";
echo "<td>".$row [ 'Gross Wt' ]." </td>";
echo "<td>".$row [ 'In Tare' ]." </td>";
echo "<td>".$row [ 'Tons' ]." Tons</td>";
echo "<td>".$row [ 'In Time' ]." </td>";
echo "<td>".$row [ 'Out Time' ]." </td>";
echo "</tr>";
}

View File

@@ -0,0 +1,36 @@
<?php
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
$sql = "SELECT Tons FROM LoadData WHERE CropDay = ( SELECT Max(CropDay) FROM LoadData)";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
$tonsin = 0;
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
{
$tonsin += $row['Tons'];
}
//end
?>
<h2>Tons In Today</h2>
<p><?php echo $tonsin; ?></p>
<?
$db = null;
?>

View File

@@ -0,0 +1,36 @@
<?php
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
$sql = "SELECT Tons FROM LoadData WHERE CropDay = ( SELECT Max(CropDay)-1 FROM LoadData)";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
$tonsin = 0;
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
{
$tonsin += $row['Tons'];
}
//end
?>
<h2>Tons In Today</h2>
<p><?php echo $tonsin; ?></p>
<?
$db = null;
?>

View File

@@ -0,0 +1,36 @@
<?php
$serverName = "CBM2K12\SQLEXPRESS";
$uid = "cbmclient";
$pwd = "ascbm2k";
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
/* Connect using SQL Server Authentication. */
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Unable to connect.</br>";
die( print_r( sqlsrv_errors(), true));
}
$sql = "SELECT * FROM LoadData ORDER BY DateIn DESC";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
$tonsin = 0;
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
{
$tonsin += $row['Tons'];
}
//end
?>
<h2>Tons In Total</h2>
<p><?php echo $tonsin; ?></p>
<?
$db = null;
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

270
lasuca/grower-account.php Normal file
View File

@@ -0,0 +1,270 @@
<?php
// phpcs:ignoreFile
require_once __DIR__ . '/grower-session.php';
require_once __DIR__ . '/inc/dbconfig.php';
require_once __DIR__ . '/inc/opendb.php';
require_once __DIR__ . '/inc/auth.php';
require_once __DIR__ . '/inc/grower_helpers.php';
$username = $_SESSION['myusername'];
$growerId = isset($_SESSION['growerid']) ? $_SESSION['growerid'] : '';
$profileMessage = '';
$profileSuccess = null;
$passwordMessage = '';
$passwordSuccess = null;
$member = auth_find_member($username);
$memberData = grower_member_defaults($member);
if ($member === null) {
$profileMessage = 'We could not locate your account record. Please contact support.';
$profileSuccess = false;
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$formType = isset($_POST['form_type']) ? $_POST['form_type'] : '';
if ($formType === 'profile') {
$emailInput = isset($_POST['email']) ? trim($_POST['email']) : '';
$farmInput = isset($_POST['growername']) ? trim($_POST['growername']) : '';
$phoneInput = isset($_POST['phone']) ? trim($_POST['phone']) : '';
$phoneDigits = preg_replace('/[^0-9A-Za-z\-\+\(\)\.\s]/', '', $phoneInput);
if ($emailInput !== '' && filter_var($emailInput, FILTER_VALIDATE_EMAIL) === false) {
$profileMessage = 'Please enter a valid email address or leave the field blank.';
$profileSuccess = false;
} else {
if (auth_update_profile($username, $emailInput, $farmInput, $phoneDigits)) {
$profileMessage = 'Profile updated successfully.';
$profileSuccess = true;
$member = auth_find_member($username) ?: $member;
$memberData = grower_member_defaults($member);
} else {
$profileMessage = 'Unable to update your profile. Please try again.';
$profileSuccess = false;
}
}
} elseif ($formType === 'password') {
$currentPassword = isset($_POST['current_password']) ? $_POST['current_password'] : '';
$newPassword = isset($_POST['new_password']) ? $_POST['new_password'] : '';
$confirmPassword = isset($_POST['confirm_password']) ? $_POST['confirm_password'] : '';
list($passwordSuccess, $passwordMessage) = auth_change_password($username, $currentPassword, $newPassword, $confirmPassword);
if ($passwordSuccess) {
$member = auth_find_member($username) ?: $member;
$memberData = grower_member_defaults($member);
}
}
}
$emailValue = isset($_POST['email']) ? trim($_POST['email']) : $memberData['email'];
$phoneValue = isset($_POST['phone']) ? trim($_POST['phone']) : $memberData['phone'];
$farmValue = isset($_POST['growername']) ? trim($_POST['growername']) : $memberData['growername'];
$lastLogin = $memberData['last_login_at'];
$passwordChanged = $memberData['password_last_changed'];
$recentFiles = $member !== null ? grower_recent_files($username, 6) : array();
require_once __DIR__ . '/inc/closedb.php';
$pageTitle = 'Grower Account';
$metaDescription = 'Update your grower portal contact information, review recent files, and manage passwords.';
?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<title><?php echo htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8'); ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="<?php echo htmlspecialchars($metaDescription, ENT_QUOTES, 'UTF-8'); ?>" />
<link rel="icon" type="image/x-icon" href="/images/favicon.ico" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/new/css/styles.css" />
<link rel="stylesheet" href="/new/css/lasuca-theme.css" />
<link rel="stylesheet" href="/new/css/pages.css" />
<link rel="stylesheet" href="/new/css/grower-portal.css" />
<link rel="stylesheet" href="/new/css/grower-dashboard.css" />
</head>
<body class="lasuca-theme theme-dark grower-portal">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container">
<a class="navbar-brand" href="/grower-dashboard.php">
<img src="/images/logo2.png" alt="LASUCA logo" />
<span>Grower Portal</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#growerNav" aria-controls="growerNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="growerNav">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link" href="/home.php">Home</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-dashboard.php">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-files.php">Daily Reports</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-account.php">Manage Account</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-logout.php">Log Out</a></li>
<?php include __DIR__ . '/inc/theme-toggle.php'; ?>
</ul>
</div>
</div>
</nav>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Grower portal</span>
<h1>Manage your account</h1>
<p>
Keep contact details current, review recent downloads, and update your password so the LASUCA team can
reach you quickly during harvest.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<?php if ($profileMessage !== '') {
$profileClass = $profileSuccess ? 'success' : 'warning'; ?>
<div class="alert alert-<?php echo $profileClass; ?>" role="alert">
<?php echo htmlspecialchars($profileMessage, ENT_QUOTES, 'UTF-8'); ?>
</div>
<?php }
if ($passwordMessage !== '') {
$passwordClass = $passwordSuccess ? 'success' : 'warning'; ?>
<div class="alert alert-<?php echo $passwordClass; ?>" role="alert">
<?php echo htmlspecialchars($passwordMessage, ENT_QUOTES, 'UTF-8'); ?>
</div>
<?php } ?>
<div class="row g-4 align-items-start">
<div class="col-lg-4">
<div class="grower-account-card grower-account-summary h-100">
<h3 class="mb-3">Account snapshot</h3>
<dl class="row">
<dt class="col-sm-6">Grower ID</dt>
<dd class="col-sm-6 text-sm-end"><?php echo htmlspecialchars((string) $growerId, ENT_QUOTES, 'UTF-8'); ?></dd>
<dt class="col-sm-6">Username</dt>
<dd class="col-sm-6 text-sm-end"><?php echo htmlspecialchars($username, ENT_QUOTES, 'UTF-8'); ?></dd>
<dt class="col-sm-6">Last login</dt>
<dd class="col-sm-6 text-sm-end"><?php echo htmlspecialchars(grower_format_datetime($lastLogin), ENT_QUOTES, 'UTF-8'); ?></dd>
<dt class="col-sm-6">Password updated</dt>
<dd class="col-sm-6 text-sm-end"><?php echo htmlspecialchars(grower_format_datetime($passwordChanged), ENT_QUOTES, 'UTF-8'); ?></dd>
<dt class="col-sm-6">File portal</dt>
<dd class="col-sm-6 text-sm-end"><a href="/grower-files.php" class="link-success">Open browser</a></dd>
</dl>
<?php if ($member !== null) {
if (!empty($recentFiles)) { ?>
<div class="mt-4">
<h3 class="mb-3">Recent files</h3>
<ul class="recent-file-list">
<?php foreach ($recentFiles as $recent) {
$recentName = htmlspecialchars($recent['name'], ENT_QUOTES, 'UTF-8');
$recentPath = htmlspecialchars($recent['path'], ENT_QUOTES, 'UTF-8');
$recentDate = htmlspecialchars(grower_format_datetime(date('Y-m-d H:i:s', $recent['modified'])), ENT_QUOTES, 'UTF-8'); ?>
<li>
<a href="<?php echo $recentPath; ?>" target="_blank" rel="noopener"><?php echo $recentName; ?></a>
<span class="activity-date"><?php echo $recentDate; ?></span>
</li>
<?php } ?>
</ul>
</div>
<?php } else { ?>
<p class="text-muted mt-4 mb-0">We haven&rsquo;t spotted any files in your grower folder yet.</p>
<?php }
} ?>
</div>
</div>
<div class="col-lg-4">
<div class="grower-account-card h-100">
<h3 class="mb-3">Contact information</h3>
<form method="post" action="" novalidate>
<input type="hidden" name="form_type" value="profile" />
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input
type="email"
class="form-control"
name="email"
id="email"
value="<?php echo htmlspecialchars($emailValue, ENT_QUOTES, 'UTF-8'); ?>"
placeholder="you@example.com"
/>
</div>
<div class="mb-4">
<label for="phone" class="form-label">Phone number</label>
<input
type="text"
class="form-control"
name="phone"
id="phone"
value="<?php echo htmlspecialchars($phoneValue, ENT_QUOTES, 'UTF-8'); ?>"
placeholder="(000) 000-0000"
/>
</div>
<div class="text">
<label for="growername" class="form-label">Farm Name</label>
<input
type="text"
class="form-control"
name="growername"
id="growername"
value="<?php echo htmlspecialchars($farmValue, ENT_QUOTES, 'UTF-8'); ?>"
placeholder="Farm Name"
/>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-success">Save contact info</button>
</div>
</form>
</div>
</div>
<div class="col-lg-4">
<div class="grower-account-card h-100">
<h3 class="mb-3">Change password</h3>
<form method="post" action="" novalidate>
<input type="hidden" name="form_type" value="password" />
<div class="mb-3">
<label for="current_password" class="form-label">Current password</label>
<input
type="password"
class="form-control"
name="current_password"
id="current_password"
autocomplete="current-password"
/>
</div>
<div class="mb-3">
<label for="new_password" class="form-label">New password</label>
<input
type="password"
class="form-control"
name="new_password"
id="new_password"
autocomplete="new-password"
/>
</div>
<div class="mb-4">
<label for="confirm_password" class="form-label">Confirm new password</label>
<input
type="password"
class="form-control"
name="confirm_password"
id="confirm_password"
autocomplete="new-password"
/>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-outline-success">Update password</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/inc/theme-footer.php';
?>

View File

@@ -0,0 +1,13 @@
<?php
// phpcs:ignoreFile
require_once __DIR__ . '/grower-session.php';
$requiredGrowerId = isset($_SESSION['growerid']) ? $_SESSION['growerid'] : null;
if ($requiredGrowerId === null) {
header('Location: /grower-login.php');
exit();
}
require __DIR__ . '/growers/dashboard.php';

359
lasuca/grower-files.php Normal file
View File

@@ -0,0 +1,359 @@
<?php
// phpcs:ignoreFile
require_once __DIR__ . '/grower-session.php';
require_once __DIR__ . '/inc/grower_helpers.php';
$username = isset($_SESSION['myusername']) ? trim($_SESSION['myusername']) : '';
if ($username === '') {
header('Location: /grower-login.php');
exit();
}
function grower_normalize_relative_path_local($path)
{
$path = str_replace('\\', '/', $path);
$segments = explode('/', $path);
$safeSegments = array();
foreach ($segments as $segment) {
if ($segment === '' || $segment === '.') {
continue;
}
if ($segment === '..') {
array_pop($safeSegments);
continue;
}
$safeSegments[] = $segment;
}
return implode('/', $safeSegments);
}
function grower_build_web_path($username, $relativePath)
{
$segments = array_merge(array($username), explode('/', str_replace('\\', '/', $relativePath)));
$segments = array_filter($segments, 'strlen');
$encoded = array_map('rawurlencode', $segments);
return 'growers/' . implode('/', $encoded);
}
$folderParam = isset($_GET['folder']) ? $_GET['folder'] : '';
$currentRelativeFolder = '';
$errors = array();
if ($folderParam !== '') {
$decoded = base64_decode($folderParam, true);
if ($decoded === false) {
$errors[] = 'The folder path you requested is invalid.';
} else {
$currentRelativeFolder = grower_normalize_relative_path_local($decoded);
}
}
$rootDir = __DIR__;
$baseDir = realpath($rootDir . '/growers/' . $username);
if ($baseDir === false || !is_dir($baseDir)) {
$errors[] = 'We could not find your grower folder yet. Please contact support for assistance.';
}
$currentDirectory = $baseDir;
if ($currentRelativeFolder !== '' && $baseDir !== false) {
$candidate = realpath($baseDir . '/' . $currentRelativeFolder);
if ($candidate === false || strpos($candidate, $baseDir) !== 0) {
$errors[] = 'That folder is no longer available. Displaying your main folder instead.';
$currentRelativeFolder = '';
} else {
$currentDirectory = $candidate;
}
}
$directories = array();
$files = array();
$totalFileSize = 0;
if ($currentDirectory !== false && is_dir($currentDirectory)) {
$items = scandir($currentDirectory);
if ($items === false) {
$errors[] = 'We could not read the contents of this folder.';
} else {
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$absoluteItem = $currentDirectory . DIRECTORY_SEPARATOR . $item;
$relativeItem = $currentRelativeFolder === '' ? $item : $currentRelativeFolder . '/' . $item;
$relativeItem = grower_normalize_relative_path_local($relativeItem);
if (is_dir($absoluteItem)) {
$itemCount = 0;
try {
$iterator = new FilesystemIterator($absoluteItem, FilesystemIterator::SKIP_DOTS);
foreach ($iterator as $unused) {
$itemCount++;
}
} catch (UnexpectedValueException $exception) {
$itemCount = 0;
}
$directories[] = array(
'name' => $item,
'encoded' => rawurlencode(base64_encode($relativeItem)),
'webPath' => '/' . grower_build_web_path($username, $relativeItem),
'items' => $itemCount,
'modified' => @filemtime($absoluteItem)
);
} elseif (is_file($absoluteItem)) {
$size = @filesize($absoluteItem);
$modified = @filemtime($absoluteItem);
$files[] = array(
'name' => $item,
'size' => ($size === false) ? 0 : $size,
'modified' => $modified,
'webPath' => '/' . grower_build_web_path($username, $relativeItem)
);
if ($size !== false) {
$totalFileSize += $size;
}
}
}
}
}
usort($directories, function ($a, $b) {
return strcasecmp($a['name'], $b['name']);
});
usort($files, function ($a, $b) {
return strcasecmp($a['name'], $b['name']);
});
$directoryCount = count($directories);
$fileCount = count($files);
$breadcrumbs = array();
$breadcrumbs[] = array('label' => 'Home', 'url' => 'grower-files.php');
if ($currentRelativeFolder !== '') {
$segments = explode('/', $currentRelativeFolder);
$compound = array();
$lastIndex = count($segments) - 1;
foreach ($segments as $index => $segment) {
$compound[] = $segment;
$encodedPath = rawurlencode(base64_encode(implode('/', $compound)));
$breadcrumbs[] = array(
'label' => $segment,
'url' => ($index === $lastIndex) ? null : 'grower-files.php?folder=' . $encodedPath
);
}
}
$parentLink = '';
if ($currentRelativeFolder !== '') {
$segments = explode('/', $currentRelativeFolder);
array_pop($segments);
$parentRelative = implode('/', $segments);
if ($parentRelative === '') {
$parentLink = 'grower-files.php';
} else {
$parentLink = 'grower-files.php?folder=' . rawurlencode(base64_encode($parentRelative));
}
}
$pageTitle = 'Grower File Browser';
$metaDescription = 'Browse and download load reports, tickets, and documents from your LASUCA grower folder.';
?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<title><?php echo htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8'); ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="<?php echo htmlspecialchars($metaDescription, ENT_QUOTES, 'UTF-8'); ?>" />
<link rel="icon" type="image/x-icon" href="/images/favicon.ico" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/new/css/styles.css" />
<link rel="stylesheet" href="/new/css/lasuca-theme.css" />
<link rel="stylesheet" href="/new/css/pages.css" />
<link rel="stylesheet" href="/new/css/grower-portal.css" />
<link rel="stylesheet" href="/new/css/grower-dashboard.css" />
</head>
<body class="lasuca-theme theme-dark grower-portal">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container">
<a class="navbar-brand" href="/grower-dashboard.php">
<img src="/images/logo2.png" alt="LASUCA logo" />
<span>Grower Portal</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#growerNav" aria-controls="growerNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="growerNav">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link" href="/home.php">Home</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-dashboard.php">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-files.php">Daily Reports</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-account.php">Manage Account</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-logout.php">Log Out</a></li>
<?php include __DIR__ . '/inc/theme-toggle.php'; ?>
</ul>
</div>
</div>
</nav>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Grower portal</span>
<h1>Your grower files</h1>
<p>
Navigate your secure LASUCA folder to download daily transaction reports. Use the
buttons below to jump between folders.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="grower-files-card">
<div class="file-browser-header">
<div>
<p class="file-browser-summary mb-1">
Currently viewing:
<strong><?php echo $currentRelativeFolder === '' ? 'Home' : htmlspecialchars($currentRelativeFolder, ENT_QUOTES, 'UTF-8'); ?></strong>
</p>
<p class="file-browser-summary mb-0">
<?php echo $directoryCount; ?> folder<?php echo $directoryCount === 1 ? '' : 's'; ?> ·
<?php echo $fileCount; ?> file<?php echo $fileCount === 1 ? '' : 's'; ?> ·
Total size <?php echo htmlspecialchars(grower_format_filesize($totalFileSize), ENT_QUOTES, 'UTF-8'); ?>
</p>
</div>
<div class="file-browser-actions">
<?php if ($parentLink !== '') { ?>
<a class="btn btn-outline-success" href="<?php echo htmlspecialchars($parentLink, ENT_QUOTES, 'UTF-8'); ?>">&larr; Up one level</a>
<?php } ?>
</div>
</div>
<nav aria-label="Breadcrumb">
<ol class="breadcrumb mb-3">
<?php foreach ($breadcrumbs as $crumb) {
$label = htmlspecialchars($crumb['label'], ENT_QUOTES, 'UTF-8');
if ($crumb['url'] !== null) { ?>
<li class="breadcrumb-item"><a href="<?php echo htmlspecialchars($crumb['url'], ENT_QUOTES, 'UTF-8'); ?>"><?php echo $label; ?></a></li>
<?php } else { ?>
<li class="breadcrumb-item active" aria-current="page"><?php echo $label; ?></li>
<?php }
} ?>
</ol>
</nav>
<?php if (!empty($errors)) { ?>
<div class="mb-3">
<?php foreach ($errors as $error) { ?>
<div class="alert alert-warning" role="alert"><?php echo htmlspecialchars($error, ENT_QUOTES, 'UTF-8'); ?></div>
<?php } ?>
</div>
<?php } ?>
<?php if ($directoryCount === 0 && $fileCount === 0) { ?>
<div class="file-empty">
<p>We didn&rsquo;t find any items in this folder yet. Drop files into your grower directory or check back after the next reporting cycle.</p>
</div>
<?php } else { ?>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col" class="text-nowrap">Details</th>
<th scope="col" class="text-nowrap">Updated</th>
<th scope="col" class="text-end">Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($directories as $directory) {
$dirName = htmlspecialchars($directory['name'], ENT_QUOTES, 'UTF-8');
$dirUrl = 'grower-files.php?folder=' . htmlspecialchars($directory['encoded'], ENT_QUOTES, 'UTF-8');
$modifiedLabel = $directory['modified']
? htmlspecialchars(grower_format_datetime(date('Y-m-d H:i:s', $directory['modified'])), ENT_QUOTES, 'UTF-8')
: 'Unknown'; ?>
<tr>
<td class="fw-semibold">
<span class="badge bg-success-subtle text-success me-2">Folder</span>
<a class="text-decoration-none" href="<?php echo $dirUrl; ?>"><?php echo $dirName; ?></a>
</td>
<td><?php echo (int) $directory['items']; ?> item<?php echo $directory['items'] === 1 ? '' : 's'; ?></td>
<td><?php echo $modifiedLabel; ?></td>
<td class="text-end">
<a class="btn btn-sm btn-outline-success" href="<?php echo $dirUrl; ?>">Open</a>
</td>
</tr>
<?php }
foreach ($files as $file) {
$fileName = htmlspecialchars($file['name'], ENT_QUOTES, 'UTF-8');
$fileSize = htmlspecialchars(grower_format_filesize($file['size']), ENT_QUOTES, 'UTF-8');
$filePath = htmlspecialchars($file['webPath'], ENT_QUOTES, 'UTF-8');
$modifiedLabel = $file['modified']
? htmlspecialchars(grower_format_datetime(date('Y-m-d H:i:s', $file['modified'])), ENT_QUOTES, 'UTF-8')
: 'Unknown'; ?>
<tr>
<td class="fw-semibold">
<span class="badge bg-primary-subtle text-primary me-2">File</span>
<a class="text-decoration-none" href="<?php echo $filePath; ?>" target="_blank" rel="noopener">
<?php echo $fileName; ?>
</a>
</td>
<td><?php echo $fileSize; ?></td>
<td><?php echo $modifiedLabel; ?></td>
<td class="text-end">
<a class="btn btn-sm btn-outline-primary" href="<?php echo $filePath; ?>" target="_blank" rel="noopener">Download</a>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<?php } ?>
</div>
</div>
</section>
</main>
<footer class="lasuca-footer">
<div class="container">
<div class="row g-3 align-items-center">
<div class="col-md-6">
<strong>Louisiana Sugar Cane Cooperative</strong><br />
341 Sugar Mill Road &middot; St. Martinville, LA 70582
</div>
<div class="col-md-6 text-md-end">
<small>&copy; <?php echo date('Y'); ?> LASUCA. All rights reserved.</small>
</div>
</div>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="/new/js/scripts.js"></script>
</body>
</html>

131
lasuca/grower-login.php Normal file
View File

@@ -0,0 +1,131 @@
<?php
// phpcs:ignoreFile
session_start();
error_reporting(E_ERROR);
require_once __DIR__ . '/inc/dbconfig.php';
require_once __DIR__ . '/inc/opendb.php';
require_once __DIR__ . '/inc/auth.php';
$myusername = isset($_POST['myusername']) ? trim($_POST['myusername']) : '';
$mypassword = isset($_POST['mypassword']) ? trim($_POST['mypassword']) : '';
$loginError = '';
if (
$_SERVER['REQUEST_METHOD'] === 'POST'
&& $myusername !== ''
&& $mypassword !== ''
) {
$member = auth_attempt_login($myusername, $mypassword);
if ($member !== null) {
$_SESSION['myusername'] = $member['username'];
$_SESSION['mypassword'] = $member['password'];
$_SESSION['growerid'] = $member['growerid'];
header('Location: growers/' . rawurlencode($myusername) . '/index.php');
exit();
}
$loginError = 'Invalid username or password.';
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$loginError = 'Please enter both your username and password.';
}
require_once __DIR__ . '/inc/closedb.php';
$pageTitle = 'Grower Login';
$metaDescription = 'Log in to the LASUCA grower portal to review load data, tickets, and alerts.';
$activeNav = 'login';
$extraStyles = array('/new/css/grower-auth.css');
$bodyClass = 'auth-page';
require __DIR__ . '/inc/theme-header.php';
?>
<main>
<header class="hero hero-auth">
<div class="container">
<div class="hero-content">
<span class="badge">Grower access</span>
<h1>Log in to manage loads, reports, and alerts.</h1>
<p>
The LASUCA grower portal keeps your harvest data, scale tickets, and mill status in one place. Sign in to stay in sync with the factory team and keep your records current.
</p>
<p class="mt-3 mb-0 text-white-50 small">Need an account? Call the LASUCA main office at <strong>(337) 394-3785</strong> and ask for Grower Relations.</p>
</div>
</div>
</header>
<section class="auth-section py-5">
<div class="container">
<div class="row g-4 justify-content-center">
<div class="col-lg-5">
<div class="auth-card">
<h2 class="auth-title">Member login</h2>
<p class="auth-subtitle">Enter the grower ID and password provided by the cooperative.</p>
<?php if ($loginError !== ''): ?>
<div class="alert alert-warning" role="alert">
<?php echo htmlspecialchars($loginError, ENT_QUOTES, 'UTF-8'); ?>
</div>
<?php endif; ?>
<form method="post" action="" class="auth-form" novalidate>
<div class="mb-3">
<label for="myusername" class="form-label">Grower ID</label>
<input
type="text"
class="form-control form-control-lg"
id="myusername"
name="myusername"
value="<?php echo htmlspecialchars($myusername, ENT_QUOTES, 'UTF-8'); ?>"
placeholder="Enter your grower ID"
autocomplete="username"
required
/>
</div>
<div class="mb-4">
<label for="mypassword" class="form-label">Password</label>
<input
type="password"
class="form-control form-control-lg"
id="mypassword"
name="mypassword"
placeholder="Enter your password"
autocomplete="current-password"
required
/>
</div>
<div class="d-grid">
<button type="submit" name="Submit" class="btn btn-primary btn-lg">Sign in</button>
</div>
</form>
<div class="auth-footnote">
<p class="mb-1">Forgot your password? Call us and we will reset it for you immediately.</p>
<p class="mb-0">Support available daily from 5:00 a.m. 9:00 p.m. during harvest.</p>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="info-card h-100">
<h3>What you&rsquo;ll find inside</h3>
<ul class="list-unstyled text-white-50 mb-4">
<li class="mb-2">• Live scale ticket feed with tonnage, net, and timestamp.</li>
<li class="mb-2">• Organized PDF archives for daily load reports.</li>
<li class="mb-2">• Mill performance snapshots and downtime alerts.</li>
<li class="mb-0">• Account tools to update contact information and passwords.</li>
</ul>
<div class="support-callout">
<h4>Need help?</h4>
<p class="mb-1">Call <strong>(337) 394-3785 ext. 244</strong> or email <a href="mailto:support@lasuca.com" class="text-decoration-none">support@lasuca.com</a>.</p>
<p class="mb-0">We&rsquo;re ready to assist with account setup and troubleshooting.</p>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/inc/theme-footer.php';
?>

18
lasuca/grower-logout.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
// phpcs:ignoreFile
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$_SESSION = array();
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
session_destroy();
header('Location: grower-login.php');
exit();

View File

@@ -0,0 +1,75 @@
<?php // phpcs:ignoreFile
session_start();
if (empty($_SESSION['myusername'])) {
header('Location: /grower-login.php');
exit();
}
$pageTitle = 'Load Data Tools';
$metaDescription = 'Review daily ticket reports and load summaries in the LASUCA grower portal.';
$activeNav = 'account';
require __DIR__ . '/inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Grower portal</span>
<h1>Welcome back, <?php echo htmlspecialchars($_SESSION['myusername'], ENT_QUOTES, 'UTF-8'); ?></h1>
<p>
Your load data folders are organized by harvest year below. Select a folder to view or download
PDF reports generated after each scale batch posts.
</p>
<a class="btn btn-outline-light btn-lg mt-3" href="/grower-login.php">Switch account</a>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<?php require __DIR__ . '/grower-quicklinks.php'; ?>
<div class="row g-4 align-items-stretch">
<div class="col-lg-6">
<div class="content-card h-100">
<h3 class="mb-3">Daily ticket reports (DTR)</h3>
<p>
Access PDF packets sorted by date, field, and contract. Each report contains net tons,
gross weight, tare, and timestamps for every load delivered during the selected period.
</p>
<ul class="feature-list">
<li>
<span class="icon">📁</span>
<div>Folders by harvest year and day make it easy to drill down.</div>
</li>
<li>
<span class="icon">⬇️</span>
<div>Download single reports or whole folders to keep offline records.</div>
</li>
<li>
<span class="icon">🔄</span>
<div>Reports refresh every evening once tickets are reconciled.</div>
</li>
</ul>
</div>
</div>
<div class="col-lg-6">
<div class="content-card h-100">
<h3 class="mb-3">Load data highlights</h3>
<p>
While you browse reports, keep an eye on summary metrics in the production dashboard. It
surfaces average grind rates, total tons, and run hours updated throughout the day.
</p>
<p class="mb-0">
Need help locating a ticket? Call grower relations at <strong>(337) 394-3785</strong> and we&rsquo;ll
email the file directly.
</p>
</div>
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/inc/theme-footer.php';
?>

108
lasuca/grower-main.php Normal file
View File

@@ -0,0 +1,108 @@
<?php // phpcs:ignoreFile
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$isGrowerLoggedIn = !empty($_SESSION['myusername']);
$pageTitle = 'Grower Portal Overview';
$metaDescription = 'Discover the tools available in the LASUCA grower portal and how to access them.';
$activeNav = 'grower';
require __DIR__ . '/inc/theme-header.php';
?>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Grower tools</span>
<h1>Everything you need to manage your crop</h1>
<p>
The LASUCA grower portal keeps daily tickets, load reports, and mill notices in one secure,
mobile-friendly dashboard. <?php echo $isGrowerLoggedIn ? 'Jump back in below to access your tools instantly.' : 'Sign in to stay synced with the factory team all season long.'; ?>
</p>
<?php if ($isGrowerLoggedIn) { ?>
<a class="btn btn-primary btn-lg mt-3" href="/grower-account.php">Open your account</a>
<?php } else { ?>
<a class="btn btn-primary btn-lg mt-3" href="/grower-login.php">Log in to the portal</a>
<?php } ?>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<?php if ($isGrowerLoggedIn) { ?>
<?php require __DIR__ . '/grower-quicklinks.php'; ?>
<?php } ?>
<p class="section-heading text-center">What&rsquo;s inside</p>
<h2 class="text-center mb-5">Tools tailored for Louisiana cane growers</h2>
<div class="content-grid two-column">
<div class="content-card">
<h3>Daily ticket reports (DTR)</h3>
<p>
Download PDF packets organized by date, block, or contract. Each ticket shows net tons,
tare, and timestamp so you can reconcile loads quickly with your field team.
</p>
</div>
<div class="content-card">
<h3>Live scale data</h3>
<p>
Track tons in and grinding rates throughout the day. Performance snapshots update from the
scale house and control room as loads are processed.
</p>
</div>
<div class="content-card">
<h3>Alerts and notices</h3>
<p>
Stay informed about downtime, weather delays, or schedule adjustments. Alerts appear in the
dashboard and are emailed to your on-file contacts.
</p>
</div>
<div class="content-card">
<h3>Account management</h3>
<p>
Update contact information, request password resets, and notify the mill of harvest changes
without waiting on phone support.
</p>
</div>
</div>
</div>
</section>
<section class="page-section-dark py-5">
<div class="container">
<p class="section-heading text-center">Getting access</p>
<h2 class="text-center mb-5">New to the portal?</h2>
<div class="row g-4 justify-content-center">
<div class="col-lg-6">
<div class="content-card">
<h3>Call grower relations</h3>
<p>
Dial <strong>(337) 394-3785</strong> and ask for grower relations. We&rsquo;ll verify your account
and send login credentials the same day.
</p>
<p class="mb-0">
For after-hours support during harvest, leave a message with your grower number and best callback
time. Our team monitors voicemails from 5:00 a.m. to 9:00 p.m.
</p>
</div>
</div>
<div class="col-lg-6">
<div class="content-card">
<h3>Already registered?</h3>
<p>
Head straight to the login page and enter your grower ID and password. Bookmark your dedicated
folder once inside for quick access to DTR files.
</p>
<p class="mb-0">
Need to update authorized contacts? Email <a href="mailto:support@lasuca.com">support@lasuca.com</a>
and we&rsquo;ll adjust permissions the same day.
</p>
</div>
</div>
</div>
</div>
</section>
</main>
<?php
require __DIR__ . '/inc/theme-footer.php';
?>

View File

@@ -0,0 +1,28 @@
<?php
// phpcs:ignoreFile
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$quickLinksUsername = isset($_SESSION['myusername']) ? $_SESSION['myusername'] : '';
$quickLinksGrowerId = isset($_SESSION['growerid']) ? $_SESSION['growerid'] : '';
if ($quickLinksUsername === '') {
return;
}
?>
<div class="grower-quick-links">
<div class="quick-links-info">
<strong>Grower Tools</strong>
<span class="quick-links-user">Signed in as <?php echo htmlspecialchars($quickLinksUsername, ENT_QUOTES, 'UTF-8'); ?><?php if ($quickLinksGrowerId !== '') { ?> (Grower <?php echo htmlspecialchars($quickLinksGrowerId, ENT_QUOTES, 'UTF-8'); ?>)<?php } ?></span>
</div>
<div class="quick-links-actions">
<a href="/home.php" class="quick-links-button">Home</a>
<a href="/grower-dashboard.php" class="quick-links-button">Dashboard</a>
<a href="/grower-main-loaddata.php" class="quick-links-button">Daily Reports</a>
<a href="/grower-files.php" class="quick-links-button">File Browser</a>
<a href="/grower-account.php" class="quick-links-button">Manage Account</a>
<a href="/grower-logout.php" class="quick-links-button logout">Log Out</a>
</div>
</div>

12
lasuca/grower-session.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
// phpcs:ignoreFile
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (empty($_SESSION['myusername'])) {
header('Location: grower-login.php');
exit();
}
?>

4
lasuca/grower-test.php Normal file
View File

@@ -0,0 +1,4 @@
<?php
session_start();
echo $_SESSION['growerid'];
?>

Some files were not shown because too many files have changed in this diff Show More