OpenXE/classes/Modules/Api/Controller/Version1/TrackingNumberController.php
2021-05-21 08:49:41 +02:00

344 lines
11 KiB
PHP

<?php
namespace Xentral\Modules\Api\Controller\Version1;
use Xentral\Components\Http\Response;
use Xentral\Modules\Api\Exception\BadRequestException;
use Xentral\Modules\Api\Exception\ValidationErrorException;
/**
* Controller zum Anlegen und Bearbeiten von Trackingnummern
*
* Die Auflistung der Trackingnummer-Ressource wird über den GenericController behandelt.
*/
class TrackingNumberController extends AbstractController
{
/**
* Trackingsnummer anlegen
*
* @return Response
*/
public function createAction()
{
$input = $this->getRequestData();
$errors = [];
// Pflichtfelder prüfen
if (empty($input['tracking'])) {
$errors[] = 'Required field "tracking" is empty.';
}
if (empty($input['internet']) && empty($input['auftrag']) && empty($input['lieferschein'])) {
$errors[] =
'Required fields "internet", "auftrag" and "lieferschein" are empty. ' .
'One of them has to be filled.';
}
if (empty($input['gewicht'])) {
$errors[] = 'Required field "gewicht" is empty.';
}
if (empty($input['anzahlpakete'])) {
$errors[] = 'Required field "anzahlpakete" is empty.';
}
if (empty($input['versendet_am'])) {
$errors[] = 'Required field "versendet_am" is empty.';
}
// Nach Pflichtfeld-Prüfung vorab Fehler anzeigen
if (count($errors) > 0) {
throw new ValidationErrorException($errors);
}
// Format der Pflichtfelder prüfen
$input['versendet_am'] = $this->ensureShippingDateFormat($input['versendet_am']);
$input['anzahlpakete'] = $this->ensureParcelCountFormat($input['anzahlpakete']);
// Prüfen ob Auftragsdaten gültig
$orderData = $this->ensureOrderData($input['lieferschein'], $input['auftrag'], $input['internet']);
// Trackingnummer-Eintrag anlegen
$resource = $this->getResource($this->resourceClass);
$bindValues = [
'adresse' => $orderData['adresseid'],
'lieferschein' => $orderData['lieferscheinid'],
'projekt' => $orderData['projektid'],
'firma' => $orderData['firmenid'],
'gewicht' => $input['gewicht'],
'anzahlpakete' => $input['anzahlpakete'],
'versendet_am' => $input['versendet_am'],
'tracking' => $input['tracking'],
'abgeschlossen' => 1,
];
$result = $resource->insert($bindValues);
return $this->sendResult($result, Response::HTTP_CREATED);
}
/**
* Trackingnummer bearbeiten
*
* @return Response
*/
public function updateAction()
{
$resource = $this->getResource($this->resourceClass);
$id = $this->getResourceId();
$resource->checkOrFail($id);
$input = $this->getRequestData();
$updateData = [];
// Format prüfen
if (isset($input['versendet_am'])) {
$updateData['versendet_am'] = $this->ensureShippingDateFormat($input['versendet_am']);
}
if (isset($input['anzahlpakete'])) {
$updateData['anzahlpakete'] = $this->ensureParcelCountFormat($input['anzahlpakete']);
}
if (isset($input['gewicht'])) {
$updateData['gewicht'] = (string)$input['gewicht'];
}
if (isset($input['tracking'])) {
$updateData['tracking'] = (string)$input['tracking'];
}
// Prüfen ob Auftragsdaten gültig
if (isset($input['lieferschein']) || isset($input['auftrag']) || isset($input['internet'])) {
$orderData = $this->ensureOrderData($input['lieferschein'], $input['auftrag'], $input['internet']);
$updateData['adresse'] = $orderData['adresseid'];
$updateData['lieferschein'] = $orderData['lieferscheinid'];
$updateData['projekt'] = $orderData['projektid'];
$updateData['firma'] = $orderData['firmenid'];
}
if (empty($updateData)) {
throw new BadRequestException('Payload is empty.');
}
$result = $resource->edit($id, $updateData);
return $this->sendResult($result);
}
/**
* Prüft ob Auftragsdaten gültig und gibt diese zurück
*
* @param string|null $deliveryNoteNumber Lieferscheinnummer
* @param string|null $orderNumber Auftragsnummer
* @param string|null $internetNumber Internetnummer aus Auftrag
*
* @throws ValidationErrorException
*
* @return array
*/
protected function ensureOrderData($deliveryNoteNumber = null, $orderNumber = null, $internetNumber = null)
{
$orderData = [];
if (!empty($deliveryNoteNumber)) {
$orderData = $this->ensureOrderDataByDeliveryNoteNumber($deliveryNoteNumber);
}
if (!empty($orderNumber)) {
$orderData = $this->ensureOrderDataByOrderNumber($orderNumber);
}
if (!empty($internetNumber)) {
$orderData = $this->ensureOrderDataByInternetNumber($internetNumber);
}
if (count($orderData) === 0) {
throw new ValidationErrorException(['Could not find order data.']);
}
return $orderData;
}
/**
* Auftrag anhand der Internetnummer (im Auftrag) finden
*
* @param string $internetNumber
*
* @throws ValidationErrorException
*
* @return array
*/
protected function ensureOrderDataByInternetNumber($internetNumber)
{
$order = $this->db->fetchAll(
'SELECT
au.id AS auftragsid,
au.projekt AS projektid,
au.adresse AS adresseid,
au.belegnr AS auftragsnummer,
au.internet AS internetnummer,
au.firma AS firmenid
FROM auftrag AS au
WHERE au.internet = :internetnummer',
['internetnummer' => $internetNumber]
);
if (count($order) === 0) {
throw new ValidationErrorException([
sprintf('Order not found with internet number "%s".', $internetNumber),
]);
}
if (count($order) > 1) {
throw new ValidationErrorException([
sprintf('Logic error: Found more than one order with internet number "%s".', $internetNumber),
]);
}
$orderData = $order[0];
$deliveryNotes = $this->db->fetchAll(
'SELECT l.id AS lieferscheinid , l.belegnr AS lieferscheinnummer
FROM lieferschein AS l
WHERE l.auftragid = :order_id',
['order_id' => $orderData['auftragsid']]
);
if (count($deliveryNotes) === 0) {
throw new ValidationErrorException([
sprintf('Delivery note not found for internet number "%s".', $internetNumber),
]);
}
if (count($deliveryNotes) > 1) {
throw new ValidationErrorException([
sprintf('Logic error: Found more than one delivery note for internet number "%s".', $internetNumber),
]);
}
$orderData['lieferscheinid'] = $deliveryNotes[0]['lieferscheinid'];
$orderData['lieferscheinnummer'] = $deliveryNotes[0]['lieferscheinnummer'];
return $orderData;
}
/**
* Auftrag anhand der Auftragsnummer finden
*
* @param string $orderNumber
*
* @throws ValidationErrorException
*
* @return array
*/
protected function ensureOrderDataByOrderNumber($orderNumber)
{
$order = $this->db->fetchAll(
'SELECT
au.id AS auftragsid,
au.projekt AS projektid,
au.adresse AS adresseid,
au.belegnr AS auftragsnummer,
au.internet AS internetnummer,
au.firma AS firmenid
FROM auftrag AS au
WHERE au.belegnr = :auftragsnummer',
['auftragsnummer' => $orderNumber]
);
if (count($order) === 0) {
throw new ValidationErrorException([
sprintf('Order not found with order number "%s".', $orderNumber),
]);
}
if (count($order) > 1) {
throw new ValidationErrorException([
sprintf('Logic error: Found more than one order with order number "%s".', $orderNumber),
]);
}
$orderData = $order[0];
$deliveryNotes = $this->db->fetchAll(
'SELECT l.id AS lieferscheinid , l.belegnr AS lieferscheinnummer
FROM lieferschein AS l
WHERE l.auftragid = :order_id',
['order_id' => $orderData['auftragsid']]
);
if (count($deliveryNotes) === 0) {
throw new ValidationErrorException([
sprintf('Delivery note not found for order number "%s".', $orderNumber),
]);
}
if (count($deliveryNotes) > 1) {
throw new ValidationErrorException([
sprintf('Logic error: Found more than one delivery note for order number "%s".', $orderNumber),
]);
}
$orderData['lieferscheinid'] = $deliveryNotes[0]['lieferscheinid'];
$orderData['lieferscheinnummer'] = $deliveryNotes[0]['lieferscheinnummer'];
return $orderData;
}
/**
* Auftrag anhand der Lieferscheinnummer finden
*
* @param string $deliveryNoteNumber
*
* @throws ValidationErrorException
*
* @return array
*/
protected function ensureOrderDataByDeliveryNoteNumber($deliveryNoteNumber)
{
$order = $this->db->fetchAll(
'SELECT
au.id AS auftragsid,
au.projekt AS projektid,
au.adresse AS adresseid,
au.belegnr AS auftragsnummer,
au.internet AS internetnummer,
l.belegnr AS lieferscheinnummer,
l.id AS lieferscheinid,
au.firma AS firmenid
FROM lieferschein AS l
INNER JOIN auftrag AS au ON l.auftragid = au.id
WHERE l.belegnr = :lieferschein',
['lieferschein' => $deliveryNoteNumber]
);
if (count($order) === 0) {
throw new ValidationErrorException([
sprintf('Order not found with delivery note number "%s".', $deliveryNoteNumber),
]);
}
if (count($order) > 1) {
throw new ValidationErrorException([
sprintf('Logic error: Found more than one order with delivery note number "%s".', $deliveryNoteNumber),
]);
}
return $order[0];
}
/**
* @param string $shippingDate
*
* @throws ValidationErrorException
*
* @return string
*/
protected function ensureShippingDateFormat($shippingDate)
{
if (!preg_match('#^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$#', $shippingDate)) {
throw new ValidationErrorException(['Field "versendet_am" does not match required format: YYYY-MM-DD']);
}
return $shippingDate;
}
/**
* @param string $parcelCount
*
* @throws ValidationErrorException
*
* @return int
*/
protected function ensureParcelCountFormat($parcelCount)
{
if (!preg_match('#^[0-9]+$#', $parcelCount)) {
throw new ValidationErrorException(['Field "anzahlpakete" does not match required format: [0-9]']);
}
return (int)$parcelCount;
}
}