Skip to content

Commit 4b8f15b

Browse files
committed
handled order shipment
1 parent 3b384ae commit 4b8f15b

File tree

20 files changed

+1171
-6
lines changed

20 files changed

+1171
-6
lines changed

app/base/controllers/Admin/Commerce/Orders.php

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
use App\Base\Abstracts\Controllers\AdminManageFrontendModelsPage;
2222
use Degami\PHPFormsApi as FAPI;
2323
use App\Base\Models\Order as OrderModel;
24+
use App\Base\Models\OrderItem;
2425
use App\Base\Models\OrderPayment;
2526
use App\Base\Models\OrderStatus;
2627
use Phpfastcache\Exceptions\PhpfastcacheSimpleCacheException;
2728
use App\Base\Models\OrderComment;
2829
use Symfony\Component\HttpFoundation\Response;
2930
use App\Base\Abstracts\Controllers\BasePage;
31+
use App\Base\Models\OrderShipment;
32+
use Symfony\Component\HttpFoundation\JsonResponse;
3033

3134
/**
3235
* "Orders" Admin Page
@@ -117,6 +120,16 @@ public function getFormDefinition(FAPI\Form $form, array &$form_state): FAPI\For
117120

118121
switch ($type) {
119122
case 'edit':
123+
if ($order->requiresShipping() || $order->getShipments()) {
124+
$this->addActionLink(
125+
'ship-btn',
126+
'ship-btn',
127+
$this->getHtmlRenderer()->getIcon('truck') .' ' . $this->getUtils()->translate('Shipments', locale: $this->getCurrentLocale()),
128+
$this->getUrl('crud.app.base.controllers.admin.json.ordershipment', ['id' => $this->getRequest()->query->get('order_id')]) . '?order_id=' . $this->getRequest()->query->get('order_id') . '&action=ship',
129+
'btn btn-sm btn-light inToolSidePanel'
130+
);
131+
}
132+
120133
// intenitional fallthrough
121134

122135
case 'view':
@@ -256,11 +269,58 @@ public function getFormDefinition(FAPI\Form $form, array &$form_state): FAPI\For
256269
'rows' => 5,
257270
]);
258271

272+
$form->addField('notify_email', [
273+
'type' => 'switchbox',
274+
'title' => 'Notify by Email',
275+
'default_value' => false,
276+
]);
277+
259278
$this->addSubmitButton($form);
260279
}
261280

262281
break;
263282

283+
case 'ship':
284+
$form->addMarkup('<h4>'.$this->getUtils()->translate('Create new Shipment', locale: $this->getCurrentLocale()).'</h4>');
285+
286+
$form->addField('shipping_method', [
287+
'type' => 'textfield',
288+
'title' => 'Shipping Method',
289+
'default_value' => '',
290+
])->addField('shipment_code', [
291+
'type' => 'textfield',
292+
'title' => 'Shipment Code',
293+
'default_value' => '',
294+
]);
295+
296+
foreach ($order->getItems() as $orderItem) {
297+
/** @var OrderItem $orderItem */
298+
if ($orderItem->requireShipping()) {
299+
$form->addField('row_'.$orderItem->getId(), [
300+
'type' => 'fieldset',
301+
'title' => $orderItem->getProduct()->getName() . ' ('.$orderItem->getProduct()->getSku().')',
302+
'inner_attributes' => [
303+
'class' => 'row',
304+
]
305+
])->addField('ship_'.$orderItem->getId(), [
306+
'type' => 'checkbox',
307+
'title' => 'Ship',
308+
'default_value' => true,
309+
'label_class' => 'mr-2',
310+
'container_class' => 'col-1',
311+
])->addField('ship_'.$orderItem->getId().'_qty', [
312+
'type' => 'number',
313+
'title' => 'Quantity',
314+
'default_value' => $orderItem->getQuantity(),
315+
'label_class' => 'mr-2',
316+
'container_class' => 'col-11 d-flex',
317+
]);
318+
}
319+
}
320+
321+
$this->addSubmitButton($form);
322+
break;
323+
264324
case 'cancel':
265325
$this->fillConfirmationForm('Do you confirm the cancellation of the selected element?', $form);
266326
break;
@@ -332,11 +392,42 @@ public function formSubmitted(FAPI\Form $form, &$form_state): mixed
332392
->setUserId($this->getCurrentUser()->getId())
333393
->setComment($values->comment)
334394
->persist();
335-
}
336395

396+
if ($values->notify_email) {
397+
$this->getUtils()->queueTemplateMail(
398+
App::getInstance()->getSiteData()->getConfigValue('commerce/emails/customer_care') ?? App::getInstance()->getSiteData()->getSiteEmail(),
399+
$order->getBillingAddress()->getEmail(),
400+
$this->getUtils()->translate("New comment on your order %s", [$order->getOrderNumber()], locale: $order->getOwner()->getLocale()),
401+
['orderNumber' => $order->getOrderNumber(), 'comment' => $values->comment],
402+
'commerce/order_comment'
403+
);
404+
}
405+
}
337406

338407
$this->addInfoFlashMessage($this->getUtils()->translate("Order updated."));
339408

409+
break;
410+
case 'ship':
411+
412+
$shipmentItems = [];
413+
foreach ($order->getItems() as $orderItem) {
414+
/** @var OrderItem $orderItem */
415+
if ($orderItem->requireShipping()) {
416+
if ($values['row_'.$orderItem->getId()]['ship_'.$orderItem->getId()]) {
417+
$shipmentItems[] = [
418+
'order_item' => $orderItem,
419+
'quantity' => $values['row_'.$orderItem->getId()]['ship_'.$orderItem->getId().'_qty'],
420+
];
421+
}
422+
}
423+
}
424+
425+
$order->ship($values['shipping_method'], $values['shipment_code'], $shipmentItems);
426+
427+
// $this->addInfoFlashMessage($this->getUtils()->translate("Shipment created."));
428+
429+
return new JsonResponse(['success' => true, 'js' => '$(\'#admin\').appAdmin(\'closeSidePanel\')']);
430+
340431
break;
341432
case 'cancel':
342433
$order->setOrderStatus(OrderStatus::getCollection()->where(['status' => OrderStatus::CANCELED])->getFirst())->persist();
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
/**
4+
* SiteBase
5+
* PHP Version 8.3
6+
*
7+
* @category CMS / Framework
8+
* @package Degami\Sitebase
9+
* @author Mirko De Grandis <degami@github.com>
10+
* @license MIT https://opensource.org/licenses/mit-license.php
11+
* @link https://github.com/degami/sitebase
12+
*/
13+
14+
namespace App\Base\Controllers\Admin\Json;
15+
16+
use Degami\Basics\Exceptions\BasicException;
17+
use App\Base\Abstracts\Controllers\AdminJsonPage;
18+
use App\Base\Controllers\Admin\Commerce\Orders;
19+
use App\Base\Models\Order;
20+
use DI\DependencyException;
21+
use DI\NotFoundException;
22+
23+
/**
24+
* order shipment JSON
25+
*/
26+
class Ordershipment extends AdminJsonPage
27+
{
28+
/**
29+
* return route path
30+
*
31+
* @return string
32+
*/
33+
public static function getRoutePath(): string
34+
{
35+
return 'json/orders/{id:\d+}/shipment';
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*
41+
* @return string
42+
*/
43+
public static function getAccessPermission(): string
44+
{
45+
return 'administer_orders';
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*
51+
* @return array
52+
* @throws BasicException
53+
* @throws DependencyException
54+
* @throws NotFoundException
55+
*/
56+
protected function getJsonData(): array
57+
{
58+
$route_data = $this->getRouteData();
59+
60+
$order = Order::load($this->getRequest()->query->get('order_id'));
61+
62+
$orderShipments = '';
63+
foreach ($order->getShipments() ?? [] as $orderShipment) {
64+
$orderShipments .= $this->getHtmlRenderer()->renderOrderShipment($orderShipment);
65+
}
66+
67+
if (!$order->requiresShipping()) {
68+
return [
69+
'success' => true,
70+
'params' => $this->getRequest()->query->all(),
71+
'html' => $orderShipments,
72+
'js' => "",
73+
];
74+
}
75+
76+
$ordersController = $this->containerMake(Orders::class);
77+
$form = $ordersController->getForm();
78+
79+
$form->setAction($this->getUrl('admin.commerce.orders') . '?action=' . $this->getRequest()->query->get('action') . ($this->getRequest()->query->get('order_id') ? '&order_id=' . $this->getRequest()->query->get('order_id') : ''));
80+
$form->addField(
81+
'order_id',
82+
[
83+
'type' => 'hidden',
84+
'default_value' => $order->getId(),
85+
]
86+
);
87+
88+
return [
89+
'success' => true,
90+
'params' => $this->getRequest()->query->all(),
91+
'html' => $orderShipments.$form->render(),
92+
'js' => "",
93+
];
94+
}
95+
}

app/base/controllers/Frontend/Commerce/Checkout/Payment.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use App\Base\Traits\CommercePageTrait;
2222
use App\Base\Models\UserSession;
2323
use Degami\PHPFormsApi as FAPI;
24+
use Exception;
2425
use HaydenPierce\ClassFinder\ClassFinder;
2526

2627
class Payment extends FormPageWithLang

app/base/event_listeners/Commerce/OrderEventListener.php

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
use App\App;
1717
use App\Base\Interfaces\EventListenerInterface;
1818
use App\Base\Models\Order;
19+
use App\Base\Models\OrderPayment;
20+
use App\Base\Models\OrderShipment;
1921
use App\Base\Models\OrderStatus;
2022
use App\Base\Models\OrderStatusChange;
23+
use App\Base\Models\Website;
2124
use Gplanchat\EventManager\Event;
2225
use Exception;
2326

@@ -27,7 +30,9 @@ public function getEventHandlers() : array
2730
{
2831
// Return an array of event handlers as required by the interface
2932
return [
30-
'order_post_persist' => [$this, 'saveStatusChange']
33+
'order_post_persist' => [$this, 'saveStatusChange'],
34+
'order_paid' => [$this, 'sendPaidNotification'],
35+
'order_shipment' => [$this, 'sendShipmentNotification']
3136
];
3237
}
3338

@@ -54,4 +59,68 @@ public function saveStatusChange(Event $e)
5459
$orderStatusChange->setOrder($order)->setStatusFrom($statusFrom)->setStatusTo($statusTo)->persist();
5560
}
5661
}
62+
63+
public function sendPaidNotification(Event $e)
64+
{
65+
/** @var Order */
66+
$order = $e->getData('object');
67+
68+
/** @var OrderPayment */
69+
$payment = $e->getData('payment');
70+
71+
try {
72+
App::getInstance()->getUtils()->queueTemplateMail(
73+
App::getInstance()->getSiteData()->getSiteEmail(),
74+
App::getInstance()->getSiteData()->getConfigValue('commerce/emails/customer_care') ?? App::getInstance()->getSiteData()->getSiteEmail(),
75+
App::getInstance()->getUtils()->translate('Your order %s has been received', [$order->getOrderNumber()], locale: $order->getOwner()->getLocale()),
76+
[
77+
'order' => [[Order::class, 'load'], ['id' => $order->getId()]],
78+
'payment' => [[OrderPayment::class, 'load'], ['id' => $payment->getId()]],
79+
'website' => [[Website::class, 'load'], ['id' => $order->getWebsiteId()]]
80+
],
81+
'commerce/new_order_customer'
82+
);
83+
} catch (\Exception $e) {
84+
App::getInstance()->getApplicationLogger()->exception($e);
85+
}
86+
87+
try {
88+
App::getInstance()->getUtils()->queueInternalMail(
89+
App::getInstance()->getSiteData()->getSiteEmail(),
90+
App::getInstance()->getSiteData()->getConfigValue('commerce/emails/customer_care') ?? App::getInstance()->getSiteData()->getSiteEmail(),
91+
App::getInstance()->getUtils()->translate('New order incoming', locale: App::getInstance()->getSiteData()->getCurrentWebsite()?->getDefaultLocale()),
92+
App::getInstance()->getUtils()->translate('New order created: %s on website %s', [$order->getOrderNumber(), App::getInstance()->getSiteData()->getCurrentWebsite()?->getSiteName()], locale: App::getInstance()->getSiteData()->getCurrentWebsite()?->getDefaultLocale())
93+
);
94+
} catch (\Exception $e) {
95+
App::getInstance()->getApplicationLogger()->exception($e);
96+
}
97+
}
98+
99+
public function sendShipmentNotification(Event $e)
100+
{
101+
/** @var Order */
102+
$order = $e->getData('object');
103+
104+
/** @var OrderShipment */
105+
$shipment = $e->getData('shipment');
106+
107+
/** @var array */
108+
$items = $e->getData('items');
109+
110+
try {
111+
App::getInstance()->getUtils()->queueTemplateMail(
112+
App::getInstance()->getSiteData()->getSiteEmail(),
113+
App::getInstance()->getSiteData()->getConfigValue('commerce/emails/customer_care') ?? App::getInstance()->getSiteData()->getSiteEmail(),
114+
App::getInstance()->getUtils()->translate('New shipment for your order %s', [$order->getOrderNumber()], locale: $order->getOwner()->getLocale()),
115+
[
116+
'order' => [[Order::class, 'load'], ['id' => $order->getId()]],
117+
'shipment' => [[OrderShipment::class, 'load'], ['id' => $shipment->getId()]],
118+
'website' => [[Website::class, 'load'], ['id' => $order->getWebsiteId()]]
119+
],
120+
'commerce/new_shipment_customer'
121+
);
122+
} catch (\Exception $e) {
123+
App::getInstance()->getApplicationLogger()->exception($e);
124+
}
125+
}
57126
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/**
4+
* SiteBase
5+
* PHP Version 8.3
6+
*
7+
* @category CMS / Framework
8+
* @package Degami\Sitebase
9+
* @author Mirko De Grandis <degami@github.com>
10+
* @license MIT https://opensource.org/licenses/mit-license.php
11+
* @link https://github.com/degami/sitebase
12+
*/
13+
14+
namespace App\Base\Migrations;
15+
16+
use App\Base\Abstracts\Migrations\DBMigration;
17+
use Degami\SqlSchema\Table;
18+
use Degami\SqlSchema\Index;
19+
use Degami\SqlSchema\ForeignKey;
20+
21+
class CreateOrderShipmentItemTableMigration extends DBMigration
22+
{
23+
protected string $tableName = 'order_shipment_item';
24+
25+
public function getName(): string
26+
{
27+
return '09.3_' . parent::getName();
28+
}
29+
30+
public function addDBTableDefinition(Table $table): Table
31+
{
32+
$table->addColumn('id', 'INT', null, ['UNSIGNED'], false)
33+
->addColumn('shipment_id', 'INT', null, ['UNSIGNED'], false)
34+
->addColumn('user_id', 'INT', null, ['UNSIGNED'], false)
35+
->addColumn('website_id', 'INT', null, ['UNSIGNED'], false)
36+
->addColumn('order_item_id', 'INT', null, ['UNSIGNED'], false)
37+
->addColumn('quantity', 'INT', null, [], false)
38+
->addColumn('created_at', 'DATETIME', null, [], false)
39+
->addColumn('updated_at', 'DATETIME', null, [], false)
40+
->addIndex(null, 'id', Index::TYPE_PRIMARY)
41+
->addForeignKey('fk_shipmentitem_website_id', ['website_id'], 'website', ['id'])
42+
->addForeignKey('fk_shipmentitem_owner_id', ['user_id'], 'user', ['id'])
43+
->addForeignKey('fk_shipmentitem_shipment_id', ['shipment_id'], 'order_shipment', ['id'], ForeignKey::ACTION_CASCADE, ForeignKey::ACTION_CASCADE)
44+
->setAutoIncrementColumn('id');
45+
46+
return $table;
47+
}
48+
}

0 commit comments

Comments
 (0)