74 lines
4.7 KiB
Markdown
74 lines
4.7 KiB
Markdown
---
|
|
task: Add print button for POS scan code and sales statistics (sold today + sold to date) on BuyViewProductMarket page
|
|
cycles: 5
|
|
context: true
|
|
private: false
|
|
started: 2026-05-16T19:01:29Z
|
|
finished: 2026-05-16T19:02:00Z
|
|
---
|
|
|
|
## files
|
|
- `resources/js/Pages/BuyViewProductMarket.vue` [lines 159-167] — existing POS QR section; add print button + statistics display
|
|
- `app/Http/Controllers/Market/ProductController.php` [lines 223-360] — `viewProductDetails` static method; add `sold_today` and `store_sold_today` to `$data` array
|
|
|
|
## steps
|
|
1. In `ProductController.php`, add `use App\Models\Market\ProductTransaction;` to the import block (after line 14) if not already present.
|
|
2. In `ProductController.php` inside `viewProductDetails`, after line 290 (`$storeProductSold = $storeProduct->pivot->sold;`), add:
|
|
```php
|
|
$storeSoldToday = ProductTransaction::where('product_id', $product->id)
|
|
->where('store_id', $targetStore->id)
|
|
->whereDate('created_at', today())
|
|
->sum('quantity');
|
|
```
|
|
3. After the `if ($targetStore)` block (before line 312 `$data = [`), add a global sold_today query:
|
|
```php
|
|
$soldToday = ProductTransaction::where('product_id', $product->id)
|
|
->whereDate('created_at', today())
|
|
->sum('quantity');
|
|
```
|
|
4. In `$data` array (lines 312-338), add after `'sold' => $product->sold,`:
|
|
```php
|
|
'sold_today' => (int) $soldToday,
|
|
'store_sold_today' => isset($storeSoldToday) ? (int) $storeSoldToday : null,
|
|
```
|
|
5. In `BuyViewProductMarket.vue`, add a `printPosCode()` function in `<script setup>` that opens a new window rendering the QR image + product name + barcode value formatted for printing, then calls `window.print()` and closes.
|
|
6. In `BuyViewProductMarket.vue`, replace the existing `pos-qr-section` block (lines 160-167) with an enhanced version that:
|
|
- Keeps the existing QR image
|
|
- Adds a "Print" button (`fas fa-print`) below the QR image (visible to `['ult','superoperator','operator']` roles OR always — per user preference; default: always visible)
|
|
- Adds a stats row below showing: `Sold Today: X` and `Total Sold: Y` using `product.sold_today`, `product.store_sold`, `product.sold`, `product.store_sold_today` — prefer store-specific values when `product.is_from_store` is true
|
|
7. Use theme variables (`var(--bg-card)`, `var(--text-primary)`) for the new stats section; no hardcoded `bg-white`/`text-dark`.
|
|
|
|
## context
|
|
### Backend — ProductController.php
|
|
- `viewProductDetails` static method at line 223; receives `$target` (hashkey) and optional `$withStores` flag
|
|
- `$targetStore` is set only when a store hash was in request (`$req->input('data.store_hash')`)
|
|
- Pivot `sold` already extracted: `$storeProductSold = $storeProduct->pivot->sold;` (line 290)
|
|
- Returned in `$data`: `'store_sold' => $storeProductSold` (line 326), `'sold' => $product->sold` (line 327)
|
|
- `ProductTransaction` model: table `prd_trx`, fields `product_id`, `store_id`, `quantity` (int), `created_at`; model at `app/Models/Market/ProductTransaction.php`
|
|
- Response format: `ResponseHelper::returnSuccessResponse($data, $data['hashkey'])` → `{ success: true, data: {...} }`
|
|
|
|
### Frontend — BuyViewProductMarket.vue
|
|
- `product` is a computed ref from `productStore.currentProduct` (line 26)
|
|
- Existing QR section (line 160-167): `v-if="product.pos_qrcode"`, shows QR via `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=...`
|
|
- `pos_qrcode` value is `md5(product_hashkey + store_hashkey)` for store products, or `barcode` or `hashkey` for standalone products
|
|
- `role` from `useAuth()` — values: `'ult'`, `'superoperator'`, `'operator'`, `'customer'`, etc.
|
|
- Print function pattern — open new window with minimal HTML:
|
|
```js
|
|
const printPosCode = () => {
|
|
const w = window.open('', '_blank', 'width=400,height=500');
|
|
w.document.write(`<html><body style="text-align:center;font-family:sans-serif">
|
|
<h3>${product.value.name}</h3>
|
|
<img src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(product.value.pos_qrcode)}" />
|
|
<p style="font-size:12px">${product.value.pos_qrcode}</p>
|
|
<script>window.onload=()=>{window.print();window.close();}<\/script>
|
|
</body></html>`);
|
|
w.document.close();
|
|
};
|
|
```
|
|
- Stats display: show `store_sold_today ?? sold_today` for "Today" and `store_sold ?? sold` for "Total" when `is_from_store` is true; otherwise use global values
|
|
|
|
## notes
|
|
- dictionary: ai-docs/dictionary.md
|
|
- linters: eslint, tsc
|
|
- constraints: Use canonical table name `prd_trx` in any raw SQL (not needed here — using Eloquent). No `bg-white`/`text-dark` hardcoded. No new routes needed — extends existing `/View/Product/Details/data` response. Definition-of-done checklist: no new page/route, so only theming + audit-field rules apply.
|