Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Order bug #205

Merged
merged 5 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions src/controllers/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Exception;
use Steamy\Core\Controller;
use Steamy\Core\Utility;
use Steamy\Model\Mailer;
use Steamy\Model\Order;
use Steamy\Model\OrderProduct;
use Steamy\Model\Product;
Expand Down Expand Up @@ -71,8 +70,6 @@ private function handleInvalidURL(): void

private function handleCheckout(): void
{
// TODO: write appropriate errors to Cart view instead of sending response code

// check if user is logged in
$signed_client = $this->getSignedInClient();
if (!$signed_client) {
Expand Down Expand Up @@ -110,24 +107,35 @@ private function handleCheckout(): void
$new_order->addLineItem($line_item);
}

// save order
$success_order = false;
// attempt to save order. An exception will be generated in case of any errors.
try {
$success_order = $new_order->save();
http_response_code($success_order ? 201 : 400);
} catch (Exception $e) {
error_log($e->getMessage());
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
return;
}

// send confirmation email if order was successfully saved
if ($success_order) {
try {
$signed_client->sendOrderConfirmationEmail($new_order);
} catch (Exception $e) {
error_log($e->getMessage());
}
// if order was unsuccessfully saved without any exceptions generated
if (!$success_order) {
http_response_code(500);
echo json_encode(['error' => "Order could not be saved for an unknown reason."]);
return;
}

// send confirmation email
try {
$success_mail = $signed_client->sendOrderConfirmationEmail($new_order);
} catch (Exception $e) {
http_response_code(503);
echo json_encode(['error' => "Order was saved but email could not be sent: " . $e->getMessage()]);
return;
}

if (!$success_mail) {
http_response_code(503);
echo json_encode(['error' => "Order was saved but email could not be sent for an unknown reason."]);
}
}

Expand Down
50 changes: 34 additions & 16 deletions src/models/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,8 @@ public function save(): bool
$update_stock_stm = $conn->prepare($query);

foreach ($this->line_items as $line_item) {
if (!empty($line_item->validate())) {
// line item contains invalid attributes
$conn->rollBack();
$conn = null;
throw new Exception("Invalid line item:" . json_encode($line_item));
}
// set order ID of line item
$line_item->setOrderID($new_order_id);

// fetch product corresponding to line item
$product = Product::getByID($line_item->getProductID());
Expand All @@ -139,22 +135,49 @@ public function save(): bool
throw new Exception("Product with ID " . $line_item->getProductID() . " does not exist");
}

// set true unit price of line item
$line_item->setUnitPrice($product->getPrice());

// get stock level for current product
$stock_level = $store->getProductStock($product->getProductID());

if ($line_item->getQuantity() > $stock_level) {
// store does not have enough stock
$conn->rollBack();
$conn = null;

$error_message = <<< EOL
Store with ID $this->store_id has insufficient stock ($stock_level) for the following line item:
Product ID = {$line_item->getProductID()} and quantity = {$line_item->getQuantity()}.
EOL;

throw new Exception($error_message);
}

// validate line item
$line_item_errors = $line_item->validate();
if (!empty($line_item_errors)) {
// line item contains invalid attributes
$conn->rollBack();
$conn = null;

$line_item_info = json_encode($line_item->toArray());
$line_item_errors = json_encode($line_item_errors);

$error_message = <<< EOL
Invalid line item:
$line_item_info

Errors:
$line_item_errors
EOL;

throw new Exception(
"Store with ID " . $this->store_id
. " has insufficient stock for product " . $line_item->getProductID()
$error_message
);
}

// insert into order_product table
$line_item->setOrderID($new_order_id);
$line_item->setUnitPrice($product->getPrice());
// insert line item into order_product table

$success = $insert_line_item_stm->execute($line_item->toArray());
if (!$success) {
Expand Down Expand Up @@ -192,14 +215,9 @@ public function save(): bool
*
* @param OrderProduct $orderProduct
* @return void
* @throws Exception
*/
public function addLineItem(OrderProduct $orderProduct): void
{
$errors = $orderProduct->validate();
if (!empty($errors)) {
throw new Exception("Invalid line item: " . json_encode($errors));
}
$this->line_items[] = $orderProduct;
}

Expand Down
9 changes: 9 additions & 0 deletions src/models/OrderProduct.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ class OrderProduct
private int $quantity;
private float $unit_price;

/**
* Create a new OrderProduct object
* @param int $product_id
* @param string $cup_size
* @param string $milk_type
* @param int $quantity
* @param float|null $unit_price If not set, the default $unit_price is -1.
* @param int|null $order_id If not set, the default $order_id is -1.
*/
public function __construct(
int $product_id,
string $cup_size,
Expand Down