# Player Trading Stores

### 1. Overview

**Codex Player Trading Stores** allows players to rent and manage their own player‑owned shops in your RedM server.

Features include:

* Players can rent configured **trading posts** in the world
* Store owners stock items directly from their inventory
* Other players can browse and buy items from these stores
* Profits are tracked per store, taxed, and collected by the owner
* Fully configurable through config + SQL, with escrow‑protected core logic

As a developer, you mainly interact with:

* `codex_shared/codex_config.lua` — main configuration
* `database.sql` — database tables
* `html/*` — optional NUI reskin files

***

### 2. Requirements & Dependencies

Required resources:

* `codex_core` — Core APIs
* `codex_notifications` — Notification system
* `ox_lib` — Menus & dialogs

#### Example `server.cfg` order

```cfg
ensure ox_lib
ensure your_framework
ensure your_inventory
ensure codex_core
ensure codex_notifications
ensure codex_player_stores
```

***

### 3. Installation

#### 3.1 Import the Database

Run `database.sql` in your MySQL database. This creates:

* `trading_stores`
* `trading_products`
* `trading_store_employees`

(See **Section 7 — Database Schema** for details.)

***

#### 3.2 Add the Resource

1. Drop the folder into your `resources` directory
2. Do not modify `fxmanifest.lua`
3. Add `ensure codex_player_stores` after dependencies in `server.cfg`

***

#### 3.3 Configure

Edit only:

```
codex_shared/codex_config.lua
```

This is the only file intended for customization.

***

### 4. Configuration (`codex_config.lua`)

#### 4.1 Keys Table

```lua
Codex = {
  Keys = {
    ["A"] = 0x7065027D,
    ["B"] = 0x4CC0E2FE,
    ["ENTER"] = 0xC7B5340A,
  },
}
```

Helper table mapping key names to RedM control hashes.

⚠️ Change only if you know the correct control codes.

***

#### 4.2 General Store Settings

```lua
OwnerStoreMarkerDistance = 5,
StorePrice = 250,
DefaultNameStore = "personal store",
```

| Setting                    | Description                                        |
| -------------------------- | -------------------------------------------------- |
| `OwnerStoreMarkerDistance` | Distance (meters) where owner marker & text appear |
| `StorePrice`               | Price to rent a store                              |
| `DefaultNameStore`         | Default display name for unrented stores           |

***

#### 4.3 TradingStores — Adding & Editing Stores

```lua
TradingStores = {
  ["market1"] = {
    name = "Ravenwood Trading Post 1",
    coords = vector4(428.87, 407.74, 108.34, 333.85),
    radius = 3.0,
    OwnerActions = vector3(426.59, 405.37, 108.37),
    ped = 'u_f_m_tumgeneralstoreowner_01',
    blip = false,
  },
}
```

Each key (e.g. `market1`) is the **store ID** and must be unique.

**Store Fields**

| Field          | Description                             |
| -------------- | --------------------------------------- |
| `name`         | Display name shown in menus & prompts   |
| `coords`       | NPC spawn position (x, y, z, heading)   |
| `radius`       | Interaction radius for renting & buying |
| `OwnerActions` | Owner management menu location          |
| `ped`          | NPC model name                          |
| `blip`         | Enable / disable map blip               |

***

#### Adding a New Store

```lua
["valentine_store1"] = {
  name = "Valentine Crossing Store",
  coords = vector4(-180.0, 626.0, 114.0, 90.0),
  radius = 3.0,
  OwnerActions = vector3(-182.0, 628.0, 114.0),
  ped = 'u_m_m_valgenstoreowner_01',
  blip = true,
},
```

Restart the resource or server.

✅ No manual DB edits required — rows are created when rented.

***

### 5. In‑Game Behaviour

#### 5.1 Renting a Store

* Player approaches unowned store NPC
* Prompt: **Purchase \[Store Name]**
* Script checks:
  * Store not owned
  * Player has enough money

On success:

* Row inserted into `trading_stores`
* Money deducted
* Ownership synced
* Owner menu opens automatically

***

#### 5.2 Buying From a Store

* Player enters owned store radius
* Prompt: **Buy from \[Store Name]**
* Product menu opens

On purchase:

* Money removed
* Store profit increases
* Stock decreases
* Item added to inventory

***

#### 5.3 Managing the Store (Owner)

Owner menu options:

* View total sales
* Collect profit (with tax applied)
* Products sold (stats)
* Tax info
* Add products

Collecting profit:

* Applies tax (default 10%)
* Pays owner
* Resets profit to 0

***

#### 5.4 Adding Products / Stocking

Flow:

1. Owner selects **Add Products**
2. Inventory list opens
3. Owner selects item
4. Inputs:
   * Price
   * Stock amount

Checks:

* Player owns enough items

On success:

* Items removed
* Product row inserted / updated

***

#### 5.5 Automatic Cleanup

Products with `stock = 0` are automatically deleted periodically from `trading_products`.

***

### 6. UI & Reskinning

Files:

* `html/index.html` — main UI
* `html/script.js` — NUI callbacks
* `html/style.css` — styling
* `html/assets/*.png` — backgrounds

#### Reskin Tips

* Replace `bg_menu.png` and `boxblack.png`
* Modify `style.css` for colors, fonts, layout

No logic changes required.

***

### 7. Database Schema

#### 7.1 `trading_stores`

| Column           | Type    | Description            |
| ---------------- | ------- | ---------------------- |
| `store_id`       | varchar | Store ID (config key)  |
| `owner`          | varchar | Player identifier      |
| `profit`         | decimal | Uncollected profit     |
| `charid`         | int     | Character ID           |
| `name`           | varchar | Custom store name      |
| `tax_percentage` | int     | Tax rate (default 10)  |
| `unpaid_taxes`   | int     | Accumulated unpaid tax |
| `totalsales`     | int     | Total items sold       |

***

#### 7.2 `trading_products`

| Column     | Type    | Description     |
| ---------- | ------- | --------------- |
| `store_id` | varchar | Store ID        |
| `item`     | varchar | Item name       |
| `label`    | varchar | Display label   |
| `price`    | decimal | Unit price      |
| `stock`    | int     | Remaining stock |

Primary key: `(store_id, item)`

***

#### 7.3 `trading_store_employees`

Reserved for future multi‑employee support.

***

### 8. Commands

#### `/refreshstores`

```lua
RegisterCommand("refreshstores", function()
  TriggerServerEvent("trading:requestOwnedStores")
end, false)
```

Forces resync of store ownership data.

***

### 9. Advanced Integration (Events & Callbacks)

⚠️ Trigger these only if you understand the internal flow.

#### 9.1 Server Events (partial)

* `trading:rentStore`
* `trading:updateStoreSettings`
* `trading:requestOwnedStores`
* `codex_store:requestStoreInfo`
* `codexstudios:addProductToStore`
* `codex_store:buyProduct`
* `codex_store:collectProfit`

***

#### 9.2 Server Callbacks

Via `CodexCore.RegisterServerCallback`:

* `codex_store:CheckOwnerItems`
* `codexstores:Buyaskmoney`

***

#### 9.3 Client Events (partial)

* `trading:sendOwnedStores`
* `trading:storeRentedSuccess`
* `codex_store:openBuyerMenu`
* `codex_store:openOwnerMenuWithStoreInfo`
* `codex_store:refreshBuyerMenu`

***

### 10. What Buyers Can Safely Edit

Editable by customers:

* `codex_shared/codex_config.lua`
  * Add / remove stores
  * Change coords, radius, prices
  * Toggle blips
* `database.sql` (initial setup only)
* `html/style.css` and `html/assets/*.png` (UI reskin)

❌ Core logic is escrow‑protected and should not be modified.

***

### 🎯 Final Notes

Codex Player Trading Stores provides a full **player‑driven economy layer** with:

* Persistent shops
* Inventory‑based stocking
* Profit tracking & taxation
* Secure escrowed logic

Perfect for immersive RP servers that want living player businesses.
