Răsfoiți Sursa

Adding quantities for items per mapping table

sebastian 16 ore în urmă
părinte
comite
e93962195e
3 a modificat fișierele cu 39 adăugiri și 9 ștergeri
  1. 24 4
      admin/mappings.php
  2. 14 5
      packing.php
  3. 1 0
      schema.sql

+ 24 - 4
admin/mappings.php

@@ -12,14 +12,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
     $iid    = (int)($_POST['itemID']     ?? 0);
     $iid    = (int)($_POST['itemID']     ?? 0);
 
 
     if ($action === 'add' && $aid > 0 && $iid > 0) {
     if ($action === 'add' && $aid > 0 && $iid > 0) {
+        $qty = max(1, (int)($_POST['quantity'] ?? 1));
         try {
         try {
-            $pdo->prepare("INSERT IGNORE INTO activity_item_map (activityID,itemID) VALUES (?,?)")
-                ->execute([$aid, $iid]);
+            $pdo->prepare("INSERT IGNORE INTO activity_item_map (activityID,itemID,quantity) VALUES (?,?,?)")
+                ->execute([$aid, $iid, $qty]);
             flash('success', 'Mapping added.');
             flash('success', 'Mapping added.');
         } catch (Exception $e) {
         } catch (Exception $e) {
             flash('error', 'Could not add mapping.');
             flash('error', 'Could not add mapping.');
         }
         }
     }
     }
+    if ($action === 'update' && $aid > 0 && $iid > 0) {
+        $qty = max(1, (int)($_POST['quantity'] ?? 1));
+        $pdo->prepare("UPDATE activity_item_map SET quantity=? WHERE activityID=? AND itemID=?")
+            ->execute([$qty, $aid, $iid]);
+        flash('success', 'Quantity updated.');
+    }
     if ($action === 'remove' && $aid > 0 && $iid > 0) {
     if ($action === 'remove' && $aid > 0 && $iid > 0) {
         $pdo->prepare("DELETE FROM activity_item_map WHERE activityID=? AND itemID=?")
         $pdo->prepare("DELETE FROM activity_item_map WHERE activityID=? AND itemID=?")
             ->execute([$aid, $iid]);
             ->execute([$aid, $iid]);
@@ -56,7 +63,7 @@ $mappedItemIds = [];
 $mappedItems   = [];
 $mappedItems   = [];
 if ($selectedAid) {
 if ($selectedAid) {
     $stmt = $pdo->prepare("
     $stmt = $pdo->prepare("
-        SELECT i.itemID, i.itemName, ig.groupName
+        SELECT i.itemID, i.itemName, ig.groupName, aim.quantity
         FROM activity_item_map aim
         FROM activity_item_map aim
         JOIN items i          ON i.itemID   = aim.itemID
         JOIN items i          ON i.itemID   = aim.itemID
         JOIN item_groups ig   ON ig.groupID = i.groupID
         JOIN item_groups ig   ON ig.groupID = i.groupID
@@ -125,6 +132,10 @@ show_alerts();
             <?php endforeach; ?>
             <?php endforeach; ?>
           </select>
           </select>
         </div>
         </div>
+        <div style="width:90px;">
+          <label>Qty</label>
+          <input type="number" name="quantity" value="1" min="1" style="margin-bottom:0;width:100%;">
+        </div>
         <button type="submit" class="btn btn-primary">➕ Add</button>
         <button type="submit" class="btn btn-primary">➕ Add</button>
       </form>
       </form>
 
 
@@ -133,13 +144,22 @@ show_alerts();
       <p style="color:var(--muted);font-size:.85rem">No items mapped yet.</p>
       <p style="color:var(--muted);font-size:.85rem">No items mapped yet.</p>
       <?php else: ?>
       <?php else: ?>
       <table class="tbl">
       <table class="tbl">
-        <thead><tr><th>#</th><th>Item</th><th>Group</th><th></th></tr></thead>
+        <thead><tr><th>#</th><th>Item</th><th>Group</th><th>Qty</th><th></th></tr></thead>
         <tbody>
         <tbody>
         <?php foreach ($mappedItems as $it): ?>
         <?php foreach ($mappedItems as $it): ?>
         <tr>
         <tr>
           <td style="color:var(--muted)"><?= $it['itemID'] ?></td>
           <td style="color:var(--muted)"><?= $it['itemID'] ?></td>
           <td><?= htmlspecialchars($it['itemName']) ?></td>
           <td><?= htmlspecialchars($it['itemName']) ?></td>
           <td><span class="badge badge-group"><?= htmlspecialchars($it['groupName']) ?></span></td>
           <td><span class="badge badge-group"><?= htmlspecialchars($it['groupName']) ?></span></td>
+          <td>
+            <form method="POST" style="display:flex;gap:.3rem;align-items:center;">
+              <input type="hidden" name="action"     value="update">
+              <input type="hidden" name="activityID" value="<?= $selectedAid ?>">
+              <input type="hidden" name="itemID"     value="<?= $it['itemID'] ?>">
+              <input type="number" name="quantity" value="<?= (int)$it['quantity'] ?>" min="1" style="margin:0;width:70px;">
+              <button class="btn btn-sm btn-primary">💾</button>
+            </form>
+          </td>
           <td style="text-align:right">
           <td style="text-align:right">
             <form method="POST" onsubmit="return confirm('Remove this mapping?')">
             <form method="POST" onsubmit="return confirm('Remove this mapping?')">
               <input type="hidden" name="action"     value="remove">
               <input type="hidden" name="action"     value="remove">

+ 14 - 5
packing.php

@@ -36,19 +36,24 @@ $stmt = $pdo->prepare("
 $stmt->execute($activityIds);
 $stmt->execute($activityIds);
 $activityNames = $stmt->fetchAll(PDO::FETCH_COLUMN);
 $activityNames = $stmt->fetchAll(PDO::FETCH_COLUMN);
 
 
-// Get all items for these activities, deduplicated, grouped by item_group
+// Get all items for these activities, deduplicated, grouped by item_group.
+// When the same item is mapped to multiple selected activities with different
+// quantities, take the MAX so we reflect the highest need across activities.
 $stmt = $pdo->prepare("
 $stmt = $pdo->prepare("
-    SELECT DISTINCT
+    SELECT
         ig.groupID,
         ig.groupID,
         ig.groupName,
         ig.groupName,
         ig.sortOrder  AS groupSort,
         ig.sortOrder  AS groupSort,
         i.itemID,
         i.itemID,
         i.itemName,
         i.itemName,
-        i.sortOrder   AS itemSort
+        i.sortOrder   AS itemSort,
+        MAX(aim.quantity) AS quantity
     FROM activity_item_map aim
     FROM activity_item_map aim
     JOIN items i          ON i.itemID   = aim.itemID
     JOIN items i          ON i.itemID   = aim.itemID
     JOIN item_groups ig   ON ig.groupID = i.groupID
     JOIN item_groups ig   ON ig.groupID = i.groupID
     WHERE aim.activityID IN ($ph)
     WHERE aim.activityID IN ($ph)
+    GROUP BY ig.groupID, ig.groupName, ig.sortOrder,
+             i.itemID, i.itemName, i.sortOrder
     ORDER BY ig.sortOrder, ig.groupID, i.sortOrder, i.itemID
     ORDER BY ig.sortOrder, ig.groupID, i.sortOrder, i.itemID
 ");
 ");
 $stmt->execute($activityIds);
 $stmt->execute($activityIds);
@@ -61,7 +66,11 @@ foreach ($allItems as $item) {
     if (!isset($grouped[$gid])) {
     if (!isset($grouped[$gid])) {
         $grouped[$gid] = ['name' => $item['groupName'], 'items' => []];
         $grouped[$gid] = ['name' => $item['groupName'], 'items' => []];
     }
     }
-    $grouped[$gid]['items'][] = ['id' => $item['itemID'], 'name' => $item['itemName']];
+    $grouped[$gid]['items'][] = [
+        'id'       => $item['itemID'],
+        'name'     => $item['itemName'],
+        'quantity' => (int)$item['quantity'],
+    ];
 }
 }
 
 
 $pageUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http')
 $pageUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http')
@@ -379,7 +388,7 @@ $totalItems = count($allItems);
             <path d="M1 4l3 3 5-6" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
             <path d="M1 4l3 3 5-6" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
           </svg>
           </svg>
         </div>
         </div>
-        <span class="item-name"><?= htmlspecialchars($item['name']) ?></span>
+        <span class="item-name"><?php if ($item['quantity'] > 1): ?><?= (int)$item['quantity'] ?>&times; <?php endif; ?><?= htmlspecialchars($item['name']) ?></span>
       </div>
       </div>
       <?php endforeach; ?>
       <?php endforeach; ?>
     </div>
     </div>

+ 1 - 0
schema.sql

@@ -40,6 +40,7 @@ CREATE TABLE IF NOT EXISTS items (
 CREATE TABLE IF NOT EXISTS activity_item_map (
 CREATE TABLE IF NOT EXISTS activity_item_map (
     activityID INT NOT NULL,
     activityID INT NOT NULL,
     itemID     INT NOT NULL,
     itemID     INT NOT NULL,
+    quantity   INT NOT NULL DEFAULT 1,
     PRIMARY KEY (activityID, itemID),
     PRIMARY KEY (activityID, itemID),
     FOREIGN KEY (activityID) REFERENCES activities(activityID) ON DELETE CASCADE,
     FOREIGN KEY (activityID) REFERENCES activities(activityID) ON DELETE CASCADE,
     FOREIGN KEY (itemID)     REFERENCES items(itemID)          ON DELETE CASCADE
     FOREIGN KEY (itemID)     REFERENCES items(itemID)          ON DELETE CASCADE