Files
Mitgliederverwaltung/lib/Service/SaleService.php
T
shahondin1624 53b3fd945a
Database Portability Tests / Integration (mysql) (push) Has been skipped
Database Portability Tests / Integration (postgres) (push) Has been skipped
Database Portability Tests / Integration (sqlite) (push) Has been skipped
Database Portability Tests / Verify no MySQL-specific SQL (push) Successful in 5s
Database Portability Tests / Unit Tests (PlatformHelper) (push) Failing after 43s
Release v0.3.2: Inventory tracking, test infra, and bugfixes
Inventory:
- General material, stock items, and sales CRUD
- Category management with CategoryPicker component
- Inventory reports service
- Database migrations and mappers

Frontend:
- Inventory view with tabs (Allgemeinmaterial, Verkaufsmaterial, Verkäufe)
- Forms for general material, stock items, and sales
- Search bar fix: flexbox wrapper with inline icon replaces broken NcTextField icon slot

Tests:
- All 1,491 tests pass (zero errors, warnings, deprecations)
- BundleImportServiceTest: fixed ZipArchive empty-file deprecation
- BundleImportService: null-coalescing for targetFields
- PHPUnit test infra: make test target via container

CLAUDE.md:
- Added Testing section as PR gating criterion
2026-04-22 10:15:22 +02:00

109 lines
3.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace OCA\Mitgliederverwaltung\Service;
use DateTime;
use OCA\Mitgliederverwaltung\Db\SaleRecord;
use OCA\Mitgliederverwaltung\Db\SaleRecordMapper;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\DB\Exception;
use Psr\Log\LoggerInterface;
/**
* Service layer for inventory sale records.
*
* Part of Issue #165 (Inventory Tracking).
*/
class SaleService {
private SaleRecordMapper $saleRecordMapper;
private AuditService $auditService;
private LoggerInterface $logger;
public function __construct(
SaleRecordMapper $saleRecordMapper,
AuditService $auditService,
LoggerInterface $logger
) {
$this->saleRecordMapper = $saleRecordMapper;
$this->auditService = $auditService;
$this->logger = $logger;
}
/**
* @return SaleRecord[]
* @throws Exception
*/
public function getSales(): array {
return $this->saleRecordMapper->findAll();
}
/**
* @throws DoesNotExistException
* @throws Exception
*/
public function getSaleById(int $id): SaleRecord {
return $this->saleRecordMapper->findById($id);
}
/**
* @throws Exception
*/
public function createSale(array $data): SaleRecord {
$qty = (int)($data['quantity'] ?? 0);
$unitPrice = (string)($data['unit_price'] ?? '0.00');
// Calculate total price = quantity × unit_price
$totalPrice = number_format((float)$unitPrice * $qty, 2, '.', '');
$record = new SaleRecord();
$record->setStockItemId($data['stock_item_id'] ?? null);
$record->setVariantId($data['variant_id'] ?? null);
$record->setDate($data['date'] ?? (new DateTime())->format('Y-m-d'));
$record->setQuantity($qty);
$record->setUnitPrice($unitPrice);
$record->setTotalPrice($totalPrice);
$record->setNotes($data['notes'] ?? null);
$record->setCreatedAt((new DateTime())->format('Y-m-d H:i:s'));
$this->saleRecordMapper->insert($record);
$this->auditService->logCreate([
'stock_item_id' => $record->getStockItemId(),
'variant_id' => $record->getVariantId(),
'date' => $record->getDate(),
'quantity' => $record->getQuantity(),
'unit_price' => $record->getUnitPrice(),
'total_price' => $record->getTotalPrice(),
], 'inventory_sale', $record->getId());
return $record;
}
/**
* @throws DoesNotExistException
* @throws Exception
*/
public function deleteSale(int $id): void {
$record = $this->saleRecordMapper->findById($id);
$this->saleRecordMapper->delete($record);
$this->auditService->logDelete('inventory_sale', $id);
}
/**
* @return SaleRecord[]
* @throws Exception
*/
public function getSalesByDateRange(?string $from, ?string $to): array {
return $this->saleRecordMapper->findByDateRange($from, $to);
}
/**
* @throws Exception
*/
public function countSalesByDateRange(?string $from, ?string $to): int {
return $this->saleRecordMapper->countByDateRange($from, $to);
}
}