# UltimatePOS Quick Reference Guide
## Common Operations & Code Patterns

---

## 🔐 Permission Checks

### Check Permission
```php
if (!auth()->user()->can('permission.name')) {
    abort(403, 'Unauthorized action.');
}
```

### Check Location Access
```php
$permitted_locations = auth()->user()->permitted_locations();

// Check if user can access specific location
if ($permitted_locations != 'all' && !in_array($location_id, $permitted_locations)) {
    abort(403, 'Unauthorized location access.');
}

// Filter query by permitted locations
if ($permitted_locations != 'all') {
    $query->whereIn('location_id', $permitted_locations);
}
```

### Get Permitted Locations Dropdown
```php
$business_id = request()->session()->get('user.business_id');
$locations = BusinessLocation::forDropdown($business_id, true); // true = show "All Locations"
```

---

## 📦 Inventory Operations

### Update Product Quantity at Location
```php
use App\Utils\ProductUtil;

$productUtil = new ProductUtil();
$productUtil->updateProductQuantity(
    $location_id,
    $product_id,
    $variation_id,
    $qty_to_add,
    $old_qty,
    $type, // e.g., 'purchase', 'sell', 'adjustment'
    $allow_negative = false
);
```

### Decrease Product Quantity
```php
$productUtil->decreaseProductQuantity(
    $product_id,
    $variation_id,
    $location_id,
    $qty_to_decrease
);
```

### Get Stock at Location
```php
use App\VariationLocationDetails;

$stock = VariationLocationDetails::where('variation_id', $variation_id)
    ->where('location_id', $location_id)
    ->first();

$qty_available = $stock ? $stock->qty_available : 0;
```

---

## 🔄 Stock Transfer

### Create Stock Transfer
```php
use App\Http\Controllers\StockTransferController;
use App\Transaction;

// 1. Validate permissions
$permitted_locations = auth()->user()->permitted_locations();
if ($permitted_locations != 'all' && 
    (!in_array($source_location_id, $permitted_locations) || 
     !in_array($dest_location_id, $permitted_locations))) {
    abort(403, 'Unauthorized location access.');
}

// 2. Create sell_transfer (source)
$sell_transfer = Transaction::create([
    'business_id' => $business_id,
    'location_id' => $source_location_id,
    'type' => 'sell_transfer',
    'status' => 'completed', // or 'pending', 'in_transit'
    'transaction_date' => now(),
    // ... other fields
]);

// 3. Create purchase_transfer (destination)
$purchase_transfer = Transaction::create([
    'business_id' => $business_id,
    'location_id' => $dest_location_id,
    'type' => 'purchase_transfer',
    'status' => 'received', // or 'pending'
    'transfer_parent_id' => $sell_transfer->id,
    'transaction_date' => now(),
    // ... other fields
]);

// 4. Update stock (if status is completed)
if ($sell_transfer->status == 'completed') {
    // Decrease at source
    $productUtil->decreaseProductQuantity(
        $product_id,
        $variation_id,
        $source_location_id,
        $qty
    );
    
    // Increase at destination
    $productUtil->updateProductQuantity(
        $dest_location_id,
        $product_id,
        $variation_id,
        $qty,
        0,
        'transfer',
        false
    );
}
```

---

## 📊 Reporting

### Get Profit & Loss
```php
use App\Utils\TransactionUtil;

$transactionUtil = new TransactionUtil();
$permitted_locations = auth()->user()->permitted_locations();

$data = $transactionUtil->getProfitLossDetails(
    $business_id,
    $location_id, // null for all locations
    $start_date,
    $end_date,
    $user_id, // optional
    $permitted_locations
);
```

### Get Purchase Totals
```php
$purchase_details = $transactionUtil->getPurchaseTotals(
    $business_id,
    $start_date,
    $end_date,
    $location_id // null for all
);
```

### Get Sell Totals
```php
$sell_details = $transactionUtil->getSellTotals(
    $business_id,
    $start_date,
    $end_date,
    $location_id // null for all
);
```

### Get Opening/Closing Stock
```php
$stock = $transactionUtil->getOpeningClosingStock(
    $business_id,
    $date,
    $location_id,
    $is_opening, // true for opening, false for closing
    $by_selling_price, // true/false
    $permitted_locations
);
```

---

## 👤 User Management

### Get Permitted Locations
```php
$user = auth()->user();
$permitted_locations = $user->permitted_locations($business_id);

// Returns: 'all' or [1, 2, 3, ...]
```

### Check Location Access
```php
$can_access = User::can_access_this_location($location_id, $business_id);
// Returns: true/false
```

### Get Users Dropdown (Filtered by Location)
```php
$users = User::forDropdown(
    $business_id,
    $prepend_none = true,
    $include_commission_agents = false,
    $prepend_all = false,
    $check_location_permission = true // Filters by location permissions
);
```

---

## 🏪 Location Operations

### Get Locations Dropdown
```php
$locations = BusinessLocation::forDropdown(
    $business_id,
    $show_all = true, // Show "All Locations" option
    $receipt_printer_type_attribute = false,
    $append_id = true,
    $check_permission = true // Respect user permissions
);
```

### Get Active Locations
```php
$locations = BusinessLocation::where('business_id', $business_id)
    ->active() // Scope: only active locations
    ->get();
```

---

## 💰 Transaction Operations

### Create Sale Transaction
```php
use App\Utils\TransactionUtil;

$transactionUtil = new TransactionUtil();

$transaction = $transactionUtil->createSellTransaction(
    $business_id,
    $input, // Array with transaction data
    $invoice_total, // Calculated totals
    $user_id,
    $uf_data = true // Unformat data
);
```

### Create Purchase Transaction
```php
$transaction = $transactionUtil->createPurchaseTransaction(
    $business_id,
    $input,
    $invoice_total,
    $user_id,
    $uf_data = true
);
```

### Get Transaction with Relations
```php
$transaction = Transaction::with([
    'contact',
    'location',
    'sell_lines.product',
    'sell_lines.variation',
    'payment_lines'
])->find($transaction_id);
```

---

## 🛒 Product Operations

### Get Products for Location
```php
use App\Product;
use App\Variation;

$products = Variation::join('variation_location_details as vld', 'vld.variation_id', 'variations.id')
    ->where('vld.location_id', $location_id)
    ->where('vld.qty_available', '>', 0)
    ->with(['product', 'variation_location_details' => function($q) use ($location_id) {
        $q->where('location_id', $location_id);
    }])
    ->get();
```

### Get Product Variations
```php
$variations = Variation::where('product_id', $product_id)
    ->with(['variation_location_details' => function($q) use ($location_id) {
        $q->where('location_id', $location_id);
    }])
    ->get();
```

---

## 🔍 Common Query Patterns

### Filter by Business
```php
$query->where('business_id', $business_id);
// or
$business_id = request()->session()->get('user.business_id');
```

### Filter by Permitted Locations
```php
$permitted_locations = auth()->user()->permitted_locations();
if ($permitted_locations != 'all') {
    $query->whereIn('location_id', $permitted_locations);
}
```

### Filter by Active Records
```php
// For models with soft deletes
$query->whereNull('deleted_at');
```

### Date Range Filter
```php
$query->whereBetween('transaction_date', [$start_date, $end_date]);
// or
$query->whereDate('transaction_date', '>=', $start_date)
      ->whereDate('transaction_date', '<=', $end_date);
```

---

## 🗄️ Database Transactions

### Standard Pattern
```php
use Illuminate\Support\Facades\DB;

DB::beginTransaction();
try {
    // Your operations here
    // ...
    
    DB::commit();
    return response()->json(['success' => true, 'msg' => 'Operation successful']);
} catch (\Exception $e) {
    DB::rollBack();
    \Log::error('Error: ' . $e->getMessage());
    return $this->respondWentWrong($e);
}
```

---

## 📝 Common Helper Methods

### Format Number (from Util)
```php
use App\Utils\Util;

$util = new Util();
$formatted = $util->num_f($number, $show_symbol = true);
$unformatted = $util->num_uf($formatted_string);
```

### Get Business ID
```php
$business_id = request()->session()->get('user.business_id');
// or
$business_id = auth()->user()->business_id;
```

### Get Current User
```php
$user = auth()->user();
$user_id = auth()->id();
```

---

## 🎨 View Helpers

### Check Permission in Blade
```blade
@can('permission.name')
    <!-- Content for users with permission -->
@endcan

@cannot('permission.name')
    <!-- Content for users without permission -->
@endcannot
```

### Check Location Access in Blade
```blade
@php
    $permitted_locations = auth()->user()->permitted_locations();
    $can_access = $permitted_locations == 'all' || in_array($location_id, $permitted_locations);
@endphp

@if($can_access)
    <!-- Location-specific content -->
@endif
```

---

## 🔧 Module Operations

### Check if Module is Enabled
```php
use App\Utils\ModuleUtil;

$moduleUtil = new ModuleUtil();
$is_enabled = $moduleUtil->isModuleInstalled('ModuleName');
```

### Check Subscription
```php
$is_subscribed = $moduleUtil->isSubscribed($business_id);
if (!$is_subscribed) {
    return $moduleUtil->expiredResponse();
}
```

---

## 📋 Common Constants

### Transaction Types
```php
'purchase'
'sell'
'expense'
'stock_adjustment'
'sell_transfer'
'purchase_transfer'
'opening_stock'
'sell_return'
'purchase_return'
```

### Transaction Statuses
```php
'received'
'pending'
'ordered'
'draft'
'final'
'in_transit'
'completed'
```

---

## 🚨 Error Handling

### Standard Error Response
```php
// In Controller (extends Controller)
return $this->respondWentWrong($exception);
// Returns: JSON with error message

// Unauthorized
return $this->respondUnauthorized('Custom message');

// Success
return $this->respondSuccess('Operation successful', $additional_data);
```

### Validation Errors
```php
if ($validator->fails()) {
    return response()->json([
        'success' => false,
        'msg' => __('validation.errors'),
        'errors' => $validator->errors()
    ]);
}
```

---

## 📞 Quick Contacts

### Get Contacts
```php
use App\Contact;

// Customers
$customers = Contact::where('business_id', $business_id)
    ->where('type', 'customer')
    ->get();

// Suppliers
$suppliers = Contact::where('business_id', $business_id)
    ->where('type', 'supplier')
    ->get();
```

---

**Last Updated:** 2025-01-27





