OpenXE/classes/Modules/AmazonVendorDF/PurchaseOrderInformationRepository.php
2021-05-21 08:49:41 +02:00

268 lines
10 KiB
PHP

<?php
namespace Xentral\Modules\AmazonVendorDF;
use Xentral\Components\Database\Database;
use Xentral\Modules\AmazonVendorDF\Data\PurchaseOrder;
use Xentral\Modules\AmazonVendorDF\Models\PurchaseOrderInformation;
use Xentral\Modules\AmazonVendorDF\Exception\ColumnNotFoundException;
use Xentral\Modules\AmazonVendorDF\Exception\DuplicatePurchaseOrderException;
use Xentral\Modules\AmazonVendorDF\Exception\PurchaseOrderNumberNotFoundException;
class PurchaseOrderInformationRepository
{
/** @var string */
private $tableName = 'amazon_vendor_df_purchase_orders';
private $columns = [
'status',
'external_id',
'raw',
'order_id',
'acknowledged',
'acknowledgement_transaction_id',
'shipping_label_requested',
'shipping_label_request_transaction_id',
'shipping_label_data',
'shipment_confirmation_transaction_id',
'created_at',
'updated_at',
'shopexport_id',
];
/** @var Database */
private $database;
public function __construct(Database $database)
{
$this->database = $database;
}
public function createPurchaseOrderInformation(PurchaseOrder $purchaseOrder, int $shopExportId):void
{
if ($this->doesPurchaseOrderInformationExist($purchaseOrder->getPurchaseOrderNumber())) {
throw new DuplicatePurchaseOrderException();
}
$statement = $this->database
->insert()
->into($this->tableName)
->cols(['external_id', 'raw', 'shopexport_id'])
->getStatement();
$values = [
'external_id' => $purchaseOrder->getPurchaseOrderNumber(),
'raw' => json_encode($purchaseOrder->getRawData()),
'shopexport_id' => json_encode($shopExportId),
];
$this->database->perform($statement, $values);
}
public function doesPurchaseOrderInformationExist(string $purchaseOrderNumber): bool
{
$statement = $this->database
->select()
->cols(['id'])
->from($this->tableName)
->where('external_id = :external_id')
->bindValue('external_id', $purchaseOrderNumber)
->limit(1);
$purchaseOrderId = $this->database->fetchRow($statement->getStatement(), $statement->getBindValues());
return !empty($purchaseOrderId['id']);
}
public function countPurchaseOrdersWaitingForImport(int $shopExportId): int
{
$statement = $this->database
->select()
->cols(['id'])
->from($this->tableName)
->where('shopexport_id = :shopexport_id')
->where('acknowledged = 0')
->where('status IS NULL')
->bindValue('shopexport_id', $shopExportId);
return count($this->database->fetchAssoc($statement->getStatement(), $statement->getBindValues()));
}
public function getNextPurchaseOrderInformationToImport(int $shopExportId): PurchaseOrderInformation
{
$statement = $this->database
->select()
->cols($this->columns)
->from($this->tableName)
->where('shopexport_id = :shopexport_id')
->where('acknowledged = 0')
->where('status IS NULL') //TODO Konstante verwenden
->bindValue('shopexport_id', $shopExportId)
->orderBy(['created_at ASC'])
->limit(1);
$data = $this->database->fetchRow($statement->getStatement(), $statement->getBindValues());
return $this->buildPurchaseOrderInformation($data);
}
/**
* @param array $constraints
*
* @return PurchaseOrderInformation[]
*/
public function listPurchaseOrderInformation(array $constraints = []): array
{
$statement = $this->database
->select()
->cols($this->columns)
->from($this->tableName);
foreach ($constraints as $constraint) {
$column = $constraint[0];
if(!in_array($column,$this->columns, false)){
throw new ColumnNotFoundException("Column '{$column}' does not exist in table {$this->tableName}");
}
$value = $constraint[1];
if ($value === null) {
$statement->where("{$column} IS NULL");
continue;
}
$operator = empty($constraint[2]) ? '=' : $constraint[2];
if ($constraint[1] instanceof \DateTime) {
$statement->where("{$column} {$operator} :{$column}");
$statement->bindValue($column, $value->format('Y-m-d H:i:s'));
} else {
$statement->where("{$column} {$operator} :{$column}");
$statement->bindValue($column, $value);
}
}
return array_map(
function (array $data) {
return $this->buildPurchaseOrderInformation($data);
},
$this->database->fetchAll($statement->getStatement(), $statement->getBindValues())
);
}
public function savePurchaseOrderInformation(PurchaseOrderInformation $purchaseOrderInformation): PurchaseOrderInformation
{
if (empty($purchaseOrderInformation->getPurchaseOrderNumber())) {
//TODO Throw
}
$columnsToSave = [];
$columnsToIgnore = ['raw', 'created_at', 'updated_at', 'shopexport_id'];
foreach ($this->columns as $column){
if(!in_array($column,$columnsToIgnore)){
$columnsToSave[] = $column;
}
}
$statement = $this->database
->update()
->cols($columnsToSave)
->table($this->tableName)
->where('external_id = :external_id')
->bindValue('external_id', $purchaseOrderInformation->getPurchaseOrderNumber())
->bindValues(
[
'order_id' => $purchaseOrderInformation->getOrderId(),
'status' => $purchaseOrderInformation->getStatus(),
'acknowledged' => $purchaseOrderInformation->isAcknowledged(),
'acknowledgement_transaction_id' => $purchaseOrderInformation->getAcknowledgementTransactionId(),
'shipping_label_requested' => $purchaseOrderInformation->isShippingLabelRequested(),
'shipping_label_request_transaction_id' => $purchaseOrderInformation->getShippingLabelRequestTransactionId(),
'shipping_label_data' => $purchaseOrderInformation->getShippingLabelData(),
'shipment_confirmation_transaction_id' => $purchaseOrderInformation->getShipmentConfirmationTransactionId(),
]
);
$this->database->perform($statement, $statement->getBindValues());
$purchaseOrderInformation->setUpdatedAt(new \DateTime());
return $purchaseOrderInformation;
}
public function getPurchaseOrderInformationByPurchaseOrderNumber(string $purchaseOrderNumber): PurchaseOrderInformation
{
$statement = $this->database
->select()
->cols($this->columns)
->from($this->tableName)
->where('external_id = :external_id')
->bindValue('external_id', $purchaseOrderNumber)
->limit(1);
$purchaseOrderData = $this->database->fetchRow($statement->getStatement(), $statement->getBindValues());
return $this->buildPurchaseOrderInformation($purchaseOrderData);
}
public function getPurchaseOrderInformationByOrderId(int $orderId): PurchaseOrderInformation
{
$statement = $this->database
->select()
->cols($this->columns)
->from($this->tableName)
->where('order_id = :order_id')
->bindValue('order_id', $orderId)
->limit(1);
$purchaseOrderData = $this->database->fetchRow($statement->getStatement(), $statement->getBindValues());
return $this->buildPurchaseOrderInformation($purchaseOrderData);
}
private function buildPurchaseOrderInformation(array $data): PurchaseOrderInformation
{
if(empty($data['external_id'])){
throw new PurchaseOrderNumberNotFoundException();
}
$purchaseOrderStatus = new PurchaseOrderInformation($data['external_id']);
if (isset($data['raw'])) {
$purchaseOrderStatus->setRaw($data['raw']);
}
if (isset($data['order_id'])) {
$purchaseOrderStatus->setOrderId($data['order_id']);
}
if (isset($data['acknowledged'])) {
$purchaseOrderStatus->setAcknowledged((bool)$data['acknowledged']);
}
if (isset($data['acknowledgement_transaction_id'])) {
$purchaseOrderStatus->setAcknowledgementTransactionId($data['acknowledgement_transaction_id']);
}
if (isset($data['shipping_label_requested'])) {
$purchaseOrderStatus->setShippingLabelRequested((bool)$data['shipping_label_requested']);
}
if (isset($data['shipping_label_request_transaction_id'])) {
$purchaseOrderStatus->setShippingLabelRequestTransactionId($data['shipping_label_request_transaction_id']);
}
if (isset($data['shipping_label_data'])) {
$purchaseOrderStatus->setShippingLabelData($data['shipping_label_data']);
}
if (isset($data['shipment_confirmation_transaction_id'])) {
$purchaseOrderStatus->setAcknowledged($data['shipment_confirmation_transaction_id']);
}
if (isset($data['created_at'])) {
$purchaseOrderStatus->setCreatedAt(\DateTime::createFromFormat('Y-m-d H:i:s', $data['created_at']));
}
if (isset($data['updated_at'])) {
$purchaseOrderStatus->setUpdatedAt(\DateTime::createFromFormat('Y-m-d H:i:s', $data['updated_at']));
}
if (isset($data['status'])) {
$purchaseOrderStatus->setStatus($data['status']);
}
return $purchaseOrderStatus;
}
}