diff --git a/README.md b/README.md index 7778dd9..cbd0209 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ of Evolution CMS for seamless and efficient **online commerce**. ## Features -- [ ] Order Management. -- [ ] Order Status Management. +- [x] Order Management. +- [x] Order Status Management. - [x] Products Catalog. - [x] Product position in each Category. - [x] Products Types. diff --git a/database/migrations/2023_12_27_190234_ecommerce_structure_tables.php b/database/migrations/2023_12_27_190234_ecommerce_structure_tables.php index 644cdd7..97309ea 100644 --- a/database/migrations/2023_12_27_190234_ecommerce_structure_tables.php +++ b/database/migrations/2023_12_27_190234_ecommerce_structure_tables.php @@ -177,12 +177,14 @@ public function up(): void $table->jsonb('products')->default(new Expression('(JSON_ARRAY())'))->comment('Product list (JSON)'); $table->decimal('cost', 9, 2)->default(0)->comment('Total order amount'); $table->char('currency', 3)->default('USD')->comment('Currency cost this order'); + $table->unsignedInteger('payment_status')->default(0)->comment('Payment status (0: pending, 1: completed, 2: failed, etc.)'); $table->unsignedInteger('status')->default(1)->comment('Order status (1: new)'); $table->boolean('is_quick')->default(false)->comment('Flag indicating if the order is a quick purchase'); $table->boolean('do_not_call')->default(false)->comment('"Do not call back" option'); $table->text('comment')->nullable()->comment('Comment on the order'); $table->string('lang', 10)->index()->default('base'); $table->jsonb('admin_notes')->default(new Expression('(JSON_ARRAY())'))->comment('Hidden comments (available only in admin panel)'); + $table->jsonb('history')->default(new Expression('(JSON_ARRAY())'))->comment('History of changes'); $table->string('identifier')->unique()->comment('Unique order key (required by some payment systems)'); $table->timestamps(); }); diff --git a/docs/pages/index.md b/docs/pages/index.md index aaaba61..feb5c5d 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -32,8 +32,8 @@ of Evolution CMS for seamless and efficient **online commerce**. ## Features -- [ ] Order Management. -- [ ] Order Status Management. +- [x] Order Management. +- [x] Order Status Management. - [x] Products Catalog. - [x] Product position in each Category. - [x] Products Types. diff --git a/lang/en/global.php b/lang/en/global.php index b4a6641..e55929d 100644 --- a/lang/en/global.php +++ b/lang/en/global.php @@ -2,6 +2,7 @@ "add" => "Add", "add_attribute_help" => "Add a new attribute.", "add_block" => "Add a block", + "add_comment" => "Add a comment...", "add_currency" => "Add a currency", "add_product" => "Add a product", "add_product_help" => "Add a new product.", @@ -13,6 +14,7 @@ "address" => "Address", "after_sum" => "After the amount", "all_products" => "All products", + "all_statuses" => "Усі статуси", "alternative_text" => "Alternative text", "are_you_sure" => "Are you sure?", "as_filter" => "As a filter", @@ -53,11 +55,15 @@ "changed_quantity" => "Quantity changed", "cities" => "Cities", "city_name" => "City name", + "client" => "Client", "code" => "Code", + "comments_and_notes" => "Comments and notes", + "completed_orders" => "Completed", "confirm_delete" => "Confirm deletion", "confirm_duplicate" => "Confirm duplication", "content" => "Content", "courier" => "Courier", + "created" => "Created", "currencies" => "Currencies", "currencies_help" => "List of available store currencies and their relationship to each other", "currencies_icon" => "fa fa-coins", @@ -67,6 +73,7 @@ "currency_name_help" => "Currency name that can be displayed on the frontend if needed sCommerce::getCurrencies(['UAH'])->first()['name']", "currency_price_configuration" => "Currency settings and price format", "currency_symbol_help" => "The currency symbol is used to display the price.", + "customer_information" => "Customer information", "deleted" => "Item deleted.", "deleted_irretrievably" => "If you press the delete button, the item will be irretrievably deleted.", "deliveries" => "Deliveries", @@ -84,6 +91,7 @@ "finish_configuring" => "Finish configuring the module according to the instructions.", "gallery" => "File gallery", "gallery_help" => "The first image of the gallery is used as a product preview. You can sort the images by moving them with the mouse.", + "history_changes" => "History of changes", "height" => "Height", "helptext" => "Help text", "helptext_help" => "Description about this Attribute in adminpanel.", @@ -126,16 +134,59 @@ "no_text" => "No text added", "not_available" => "Not available", "not_found" => "Not found", + "not_selected_or_unknown" => "Not selected or unknown", "not_writable" => "The file ../core/custom/config/seiger/settings/sCommerce.php is not writable.", "not_writable_currencies" => "The file ../core/custom/config/seiger/settings/sCommerceCurrencies.php is not writable.", "on_order" => "On order", + "one_click" => "1 Click", "only_display" => "only display", + "order" => "Order Details", + "order_cost" => "Order cost", + "order_currency" => "Order currency", + "order_help" => "View all order details, including customer information, products, statuses, and payment.", + "order_icon" => "fa fa-clipboard-list", + "order_number" => "Order number", + "order_status" => "Order status", + "order_status_canceled" => "Canceled", + "order_status_completed" => "Completed", + "order_status_confirmed" => "Confirmed", + "order_status_delivered" => "Delivered", + "order_status_deleted" => "Deleted", + "order_status_failed" => "Failed", + "order_status_management" => "Order status management", + "order_status_new" => "New", + "order_status_on_hold" => "On Hold", + "order_status_processing" => "Processing", + "order_status_packing" => "Packing", + "order_status_ready_for_shipment" => "Ready for Shipment", + "order_status_return_requested" => "Return Requested", + "order_status_returned" => "Returned", + "order_status_shipped" => "Shipped", + "orders" => "Orders", + "orders_help" => "Manage and view customer orders.", + "orders_icon" => "fa fa-shopping-cart", "orders_on" => "Order", "orders_on_help" => "Enable the functionality of orders on the site.", "payment" => "Payment", "payment_help" => "Editing payment parameters.", "payment_icon" => "fa fa-university", "payment_name" => "Payment method name", + "payment_information" => "Payment information", + "payment_status" => "Payment status", + "payment_status_awaiting_confirmation" => "Awaiting Confirmation", + "payment_status_authorized" => "Authorized", + "payment_status_canceled" => "Canceled", + "payment_status_disputed" => "Disputed", + "payment_status_expired" => "Expired", + "payment_status_failed" => "Failed", + "payment_status_paid" => "Paid", + "payment_status_partially_paid" => "Partially Paid", + "payment_status_partially_refunded" => "Partially Refunded", + "payment_status_pending" => "Pending Payment", + "payment_status_pending_verification" => "Pending Verification", + "payment_status_refund_requested" => "Refund Requested", + "payment_status_refunded" => "Refunded", + "payment_status_rejected" => "Rejected", "payments" => "Payments", "payments_help" => "List of available store payments and their settings.", "payments_icon" => "fa fa-wallet", @@ -179,6 +230,7 @@ "products" => "Products", "products_help" => "List of all store products.", "products_icon" => "fa fa-store-alt", + "products_in_order" => "Products in order", "published_help" => "Mark to publish immediately after saving.", "publisheds" => "Published", "inventory" => "Quantity", @@ -196,6 +248,8 @@ "reviews" => "Reviews", "reviews_help" => "User reviews of your store's products.", "reviews_icon" => "fa fas fa-grin-stars", + "shipping_cost" => "Shipping cost", + "shipping_information" => "Shipping information", "search_among_attributes" => "Search among attributes", "search_among_products" => "Search among products", "settings" => "Settings", @@ -209,15 +263,20 @@ "sortproducts" => "Sort by position", "sortproducts_help" => "Sorting products by position in a category", "sortproducts_icon" => "fa fa-sort", + "status" => "Status", + "sum" => "Sum", "symbol" => "Symbol", + "system" => "System", "text_block" => "Text block", "technical_parameter_for_delivery" => "technical parameter of the product that can be taken into account during delivery.", "title" => "Commerce", "to_list_attributes" => "To list attributes", "to_list_deliveries" => "To list deliveries", + "to_list_orders" => "To list orders", "to_list_payments" => "To list payments", "to_list_products" => "To list products", "to_list_reviews" => "To list reviews", + "total_orders" => "Total orders", "total_products" => "Total products", "total_reviews" => "Total reviews", "turned_off" => "turned off", @@ -250,7 +309,10 @@ "type_subscription" => "Subscription", "type_variable" => "Variable", "type_virtual" => "Virtual", + "quantity" => "Quantity", + "unprocessed_orders" => "Unprocessed", "unpublisheds" => "Unpublished", + "user_unknown" => "User unknown", "value" => "Value", "views" => "Views", "views_on_help" => "Enable product views counter functionality.", @@ -261,6 +323,7 @@ "weight" => "Weight", "width" => "Width", "with_id" => "With ID", + "working_orders" => "In Progress", "you_sure" => "Are you sure?", "you_sure_duplicate" => "Are you sure you want to duplicate?", ]; \ No newline at end of file diff --git a/lang/ru/global.php b/lang/ru/global.php index ad1d731..8d08496 100644 --- a/lang/ru/global.php +++ b/lang/ru/global.php @@ -2,6 +2,7 @@ "add" => "Додати", "add_attribute_help" => "Додати новий атрибут.", "add_block" => "Додати блок", + "add_comment" => "Додати коментар...", "add_currency" => "Додати валюту", "add_product" => "Додати товар", "add_product_help" => "Додати новий товар.", @@ -13,6 +14,7 @@ "address" => "Адреса", "after_sum" => "Після суми", "all_products" => "Всі товари", + "all_statuses" => "Усі статуси", "alternative_text" => "Альтернативний текст", "are_you_sure" => "Ви впевнені?", "as_filter" => "Як фільтр", @@ -53,11 +55,15 @@ "changed_quantity" => "Кількість змінено", "cities" => "Міста", "city_name" => "Назва міста", + "client" => "Клієнт", "code" => "Код", + "comments_and_notes" => "Коментарі та нотатки", + "completed_orders" => "Завершені", "confirm_copy" => "Підтвердити копіювання", "confirm_delete" => "Підтвердити видалення", "content" => "Контент", "courier" => "Кур'єр", + "created" => "Створено", "currencies" => "Валюти", "currencies_help" => "Список доступних валют магазину та їх відношення одна до одної.", "currencies_icon" => "fa fa-coins", @@ -67,6 +73,7 @@ "currency_name_help" => "Назва валюти, яку можна відобразити на фронтенд за потреби sCommerce::getCurrencies(['UAH'])->first()['name']", "currency_price_configuration" => "Налаштування валют та формат ціни", "currency_symbol_help" => "Символ валюти використовується для відображення ціни.", + "customer_information" => "Інформація про замовника", "deleted" => "Запис видалено.", "deleted_irretrievably" => "Якщо Ви натиснете кнопку видалити, елемент буде видалено безповоротно.", "deliveries" => "Доставки", @@ -84,6 +91,7 @@ "finish_configuring" => "Завершіть налаштування модуля згідно інструкції.", "gallery" => "Галерея файлів", "gallery_help" => "Перше зображення галереї використовується в якості превю товара. Ви маєте можливість сортувати зображення шляхом їх переміщення мишкою.", + "history_changes" => "Історія змін", "height" => "Висота", "helptext" => "Довідковий текст", "helptext_help" => "Опис цього атрибута в панелі адміністратора.", @@ -126,16 +134,59 @@ "no_text" => "Текст не додано", "not_available" => "Немає в наявності", "not_found" => "Не знайдено", + "not_selected_or_unknown" => "Не обрано або не відомо", "not_writable" => "Файл ../core/custom/config/seiger/settings/sCommerce.php не доступний для запису.", "not_writable_currencies" => "Файл ../core/custom/config/seiger/settings/sCommerceCurrencies.php не доступний для запису.", "on_order" => "Під замовлення", + "one_click" => "1 клік", "only_display" => "лише відобразити", + "order" => "Деталі замовлення", + "order_cost" => "Вартість замовлення", + "order_currency" => "Валюта замовлення", + "order_help" => "Перегляд всіх деталей замовлення, включаючи інформацію про клієнта, товари, статуси та платіж.", + "order_icon" => "fa fa-clipboard-list", + "order_number" => "Номер замовлення", + "order_status" => "Статус замовлення", + "order_status_canceled" => "Скасовано", + "order_status_completed" => "Завершено", + "order_status_confirmed" => "Підтверджено", + "order_status_delivered" => "Доставлено", + "order_status_deleted" => "Видалено", + "order_status_failed" => "Помилка", + "order_status_management" => "Керування статусом замовлення", + "order_status_new" => "Нове", + "order_status_on_hold" => "На очікуванні", + "order_status_processing" => "В обробці", + "order_status_packing" => "Упаковка", + "order_status_ready_for_shipment" => "Готове до відправлення", + "order_status_return_requested" => "Запит на повернення", + "order_status_returned" => "Повернуте", + "order_status_shipped" => "Відправлено", + "orders" => "Замовлення", + "orders_help" => "Управляйте та переглядайте замовлення клієнтів.", + "orders_icon" => "fa fa-shopping-cart", "orders_on" => "Замовлення", "orders_on_help" => "Ввімкнути функціонал замовлень на сайті.", "payment" => "Платіж", "payment_help" => "Редагування параметрів платежа.", "payment_icon" => "fa fa-university", "payment_name" => "Назва платіжного методу", + "payment_information" => "Інформація про платіж", + "payment_status" => "Статус оплати", + "payment_status_awaiting_confirmation" => "Очікує на підтвердження", + "payment_status_authorized" => "Авторизовано", + "payment_status_canceled" => "Скасовано", + "payment_status_disputed" => "Спір", + "payment_status_expired" => "Термін дії закінчився", + "payment_status_failed" => "Не вдалося", + "payment_status_paid" => "Оплачено", + "payment_status_partially_paid" => "Частково оплачено", + "payment_status_partially_refunded" => "Частково повернуто", + "payment_status_pending" => "Очікує на оплату", + "payment_status_pending_verification" => "Очікує на перевірку", + "payment_status_refund_requested" => "Запит на повернення", + "payment_status_refunded" => "Повернуто", + "payment_status_rejected" => "Відхилено", "payments" => "Платежі", "payments_help" => "Список доступних оплат магазину та їх налаштування.", "payments_icon" => "fa fa-wallet", @@ -179,6 +230,7 @@ "products" => "Товари", "products_help" => "Перелік всіх товарів магазину.", "products_icon" => "fa fa-store-alt", + "products_in_order" => "Товари в замовленні", "published_help" => "Відзначте, щоб опублікувати відразу після збереження.", "publisheds" => "Опублікованих", "inventory" => "Залишок", @@ -196,6 +248,8 @@ "reviews" => "Відгуки", "reviews_help" => "Відгуки користувачів щодо продуктів вашого магазина.", "reviews_icon" => "fa fas fa-grin-stars", + "shipping_cost" => "Вартість доставки", + "shipping_information" => "Інформація про доставку", "search_among_attributes" => "Пошук серед атрибутів", "search_among_products" => "Пошук серед товарів", "settings" => "Конфігурація", @@ -209,15 +263,20 @@ "sortproducts" => "Сортування за позицією", "sortproducts_help" => "Сортування товарів за позицією в категорії ", "sortproducts_icon" => "fa fa-sort", + "status" => "Статус", + "sum" => "Сума", "symbol" => "Символ", + "system" => "Система", "technical_parameter_for_delivery" => "технічний параметр товару, який можна враховувати під час доставки.", "text_block" => "Текстовий блок", "title" => "Комерція", "to_list_attributes" => "До списку атрибутів", "to_list_deliveries" => "До списку доставок", + "to_list_orders" => "До списку замовлень", "to_list_payments" => "До списку платежів", "to_list_products" => "До списку товарів", "to_list_reviews" => "До списку відгуків", + "total_orders" => "Загальна кількість замовлень", "total_products" => "Загальна кількість товарів", "total_reviews" => "Загальна кількість відгуків", "turned_off" => "вимкнено", @@ -250,7 +309,10 @@ "type_subscription" => "Підписка", "type_variable" => "Варіативний", "type_virtual" => "Віртуальний", + "quantity" => "Кількість", + "unprocessed_orders" => "Не оброблені", "unpublisheds" => "Не опублікованих", + "user_unknown" => "Користувач не відомий", "value" => "Значення", "views" => "Перегляди", "views_on_help" => "Ввімкнути функціонал підрахунку переглядів товару.", @@ -261,6 +323,7 @@ "weight" => "Вага", "width" => "Ширина", "with_id" => "з ID", + "working_orders" => "В роботі", "you_sure" => "Ви впевнені, що хочете видалити запис", "you_sure_copy" => "Ви впевнені, що хочете скопіювати запис", ]; \ No newline at end of file diff --git a/lang/uk/global.php b/lang/uk/global.php index ad1d731..8d08496 100644 --- a/lang/uk/global.php +++ b/lang/uk/global.php @@ -2,6 +2,7 @@ "add" => "Додати", "add_attribute_help" => "Додати новий атрибут.", "add_block" => "Додати блок", + "add_comment" => "Додати коментар...", "add_currency" => "Додати валюту", "add_product" => "Додати товар", "add_product_help" => "Додати новий товар.", @@ -13,6 +14,7 @@ "address" => "Адреса", "after_sum" => "Після суми", "all_products" => "Всі товари", + "all_statuses" => "Усі статуси", "alternative_text" => "Альтернативний текст", "are_you_sure" => "Ви впевнені?", "as_filter" => "Як фільтр", @@ -53,11 +55,15 @@ "changed_quantity" => "Кількість змінено", "cities" => "Міста", "city_name" => "Назва міста", + "client" => "Клієнт", "code" => "Код", + "comments_and_notes" => "Коментарі та нотатки", + "completed_orders" => "Завершені", "confirm_copy" => "Підтвердити копіювання", "confirm_delete" => "Підтвердити видалення", "content" => "Контент", "courier" => "Кур'єр", + "created" => "Створено", "currencies" => "Валюти", "currencies_help" => "Список доступних валют магазину та їх відношення одна до одної.", "currencies_icon" => "fa fa-coins", @@ -67,6 +73,7 @@ "currency_name_help" => "Назва валюти, яку можна відобразити на фронтенд за потреби sCommerce::getCurrencies(['UAH'])->first()['name']", "currency_price_configuration" => "Налаштування валют та формат ціни", "currency_symbol_help" => "Символ валюти використовується для відображення ціни.", + "customer_information" => "Інформація про замовника", "deleted" => "Запис видалено.", "deleted_irretrievably" => "Якщо Ви натиснете кнопку видалити, елемент буде видалено безповоротно.", "deliveries" => "Доставки", @@ -84,6 +91,7 @@ "finish_configuring" => "Завершіть налаштування модуля згідно інструкції.", "gallery" => "Галерея файлів", "gallery_help" => "Перше зображення галереї використовується в якості превю товара. Ви маєте можливість сортувати зображення шляхом їх переміщення мишкою.", + "history_changes" => "Історія змін", "height" => "Висота", "helptext" => "Довідковий текст", "helptext_help" => "Опис цього атрибута в панелі адміністратора.", @@ -126,16 +134,59 @@ "no_text" => "Текст не додано", "not_available" => "Немає в наявності", "not_found" => "Не знайдено", + "not_selected_or_unknown" => "Не обрано або не відомо", "not_writable" => "Файл ../core/custom/config/seiger/settings/sCommerce.php не доступний для запису.", "not_writable_currencies" => "Файл ../core/custom/config/seiger/settings/sCommerceCurrencies.php не доступний для запису.", "on_order" => "Під замовлення", + "one_click" => "1 клік", "only_display" => "лише відобразити", + "order" => "Деталі замовлення", + "order_cost" => "Вартість замовлення", + "order_currency" => "Валюта замовлення", + "order_help" => "Перегляд всіх деталей замовлення, включаючи інформацію про клієнта, товари, статуси та платіж.", + "order_icon" => "fa fa-clipboard-list", + "order_number" => "Номер замовлення", + "order_status" => "Статус замовлення", + "order_status_canceled" => "Скасовано", + "order_status_completed" => "Завершено", + "order_status_confirmed" => "Підтверджено", + "order_status_delivered" => "Доставлено", + "order_status_deleted" => "Видалено", + "order_status_failed" => "Помилка", + "order_status_management" => "Керування статусом замовлення", + "order_status_new" => "Нове", + "order_status_on_hold" => "На очікуванні", + "order_status_processing" => "В обробці", + "order_status_packing" => "Упаковка", + "order_status_ready_for_shipment" => "Готове до відправлення", + "order_status_return_requested" => "Запит на повернення", + "order_status_returned" => "Повернуте", + "order_status_shipped" => "Відправлено", + "orders" => "Замовлення", + "orders_help" => "Управляйте та переглядайте замовлення клієнтів.", + "orders_icon" => "fa fa-shopping-cart", "orders_on" => "Замовлення", "orders_on_help" => "Ввімкнути функціонал замовлень на сайті.", "payment" => "Платіж", "payment_help" => "Редагування параметрів платежа.", "payment_icon" => "fa fa-university", "payment_name" => "Назва платіжного методу", + "payment_information" => "Інформація про платіж", + "payment_status" => "Статус оплати", + "payment_status_awaiting_confirmation" => "Очікує на підтвердження", + "payment_status_authorized" => "Авторизовано", + "payment_status_canceled" => "Скасовано", + "payment_status_disputed" => "Спір", + "payment_status_expired" => "Термін дії закінчився", + "payment_status_failed" => "Не вдалося", + "payment_status_paid" => "Оплачено", + "payment_status_partially_paid" => "Частково оплачено", + "payment_status_partially_refunded" => "Частково повернуто", + "payment_status_pending" => "Очікує на оплату", + "payment_status_pending_verification" => "Очікує на перевірку", + "payment_status_refund_requested" => "Запит на повернення", + "payment_status_refunded" => "Повернуто", + "payment_status_rejected" => "Відхилено", "payments" => "Платежі", "payments_help" => "Список доступних оплат магазину та їх налаштування.", "payments_icon" => "fa fa-wallet", @@ -179,6 +230,7 @@ "products" => "Товари", "products_help" => "Перелік всіх товарів магазину.", "products_icon" => "fa fa-store-alt", + "products_in_order" => "Товари в замовленні", "published_help" => "Відзначте, щоб опублікувати відразу після збереження.", "publisheds" => "Опублікованих", "inventory" => "Залишок", @@ -196,6 +248,8 @@ "reviews" => "Відгуки", "reviews_help" => "Відгуки користувачів щодо продуктів вашого магазина.", "reviews_icon" => "fa fas fa-grin-stars", + "shipping_cost" => "Вартість доставки", + "shipping_information" => "Інформація про доставку", "search_among_attributes" => "Пошук серед атрибутів", "search_among_products" => "Пошук серед товарів", "settings" => "Конфігурація", @@ -209,15 +263,20 @@ "sortproducts" => "Сортування за позицією", "sortproducts_help" => "Сортування товарів за позицією в категорії ", "sortproducts_icon" => "fa fa-sort", + "status" => "Статус", + "sum" => "Сума", "symbol" => "Символ", + "system" => "Система", "technical_parameter_for_delivery" => "технічний параметр товару, який можна враховувати під час доставки.", "text_block" => "Текстовий блок", "title" => "Комерція", "to_list_attributes" => "До списку атрибутів", "to_list_deliveries" => "До списку доставок", + "to_list_orders" => "До списку замовлень", "to_list_payments" => "До списку платежів", "to_list_products" => "До списку товарів", "to_list_reviews" => "До списку відгуків", + "total_orders" => "Загальна кількість замовлень", "total_products" => "Загальна кількість товарів", "total_reviews" => "Загальна кількість відгуків", "turned_off" => "вимкнено", @@ -250,7 +309,10 @@ "type_subscription" => "Підписка", "type_variable" => "Варіативний", "type_virtual" => "Віртуальний", + "quantity" => "Кількість", + "unprocessed_orders" => "Не оброблені", "unpublisheds" => "Не опублікованих", + "user_unknown" => "Користувач не відомий", "value" => "Значення", "views" => "Перегляди", "views_on_help" => "Ввімкнути функціонал підрахунку переглядів товару.", @@ -261,6 +323,7 @@ "weight" => "Вага", "width" => "Ширина", "with_id" => "з ID", + "working_orders" => "В роботі", "you_sure" => "Ви впевнені, що хочете видалити запис", "you_sure_copy" => "Ви впевнені, що хочете скопіювати запис", ]; \ No newline at end of file diff --git a/module/sCommerceModule.php b/module/sCommerceModule.php index d02d6f8..81c3303 100644 --- a/module/sCommerceModule.php +++ b/module/sCommerceModule.php @@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; use Seiger\sCommerce\Controllers\sCommerceController; +use Seiger\sCommerce\Facades\sCheckout; use Seiger\sCommerce\Facades\sCommerce; use Seiger\sCommerce\Interfaces\DeliveryMethodInterface; use Seiger\sCommerce\Interfaces\PaymentMethodInterface; @@ -18,6 +19,7 @@ use Seiger\sCommerce\Models\sAttributeValue; use Seiger\sCommerce\Models\sCategory; use Seiger\sCommerce\Models\sDeliveryMethod; +use Seiger\sCommerce\Models\sOrder; use Seiger\sCommerce\Models\sPaymentMethod; use Seiger\sCommerce\Models\sProduct; use Seiger\sCommerce\Models\sProductTranslate; @@ -36,8 +38,12 @@ $get = request()->get ?? (sCommerce::config('basic.orders_on', 1) == 1 ? "orders" : "products"); $iUrl = (int)request()->input('i', 0) > 0 ? '&i=' . (int)request()->input('i', 0) : ''; $editor = []; +$tabs = []; -$tabs = ['products', 'reviews', 'attributes']; +if (sCommerce::config('basic.orders_on', 1) == 1) { + $tabs[] = 'orders'; +} +$tabs = array_merge($tabs, ['products', 'reviews', 'attributes']); if (count(sCommerce::config('basic.available_currencies', [])) > 1 && trim(sCommerce::config('basic.main_currency', ''))) { $tabs[] = 'currencies'; } @@ -66,6 +72,86 @@ } } case "orders": + $perpage = Cookie::get('scom_orders_page_items', 50); + $dbStatuses = array_flip(sOrder::select('status')->distinct()->pluck('status')->toArray()); + $status = request()->input('status', 0); + $status = isset($dbStatuses[$status]) ? $status : 0; + $order = request()->input('order', 'id'); + $direc = request()->input('direc', 'desc'); + + $query = sOrder::query()->select('*'); + $query->selectRaw('JSON_UNQUOTE(JSON_EXTRACT(user_info, "$.name")) as client'); + $query->orderBy($order, $direc); + + $unprocessedes = [ + sOrder::ORDER_STATUS_NEW, + sOrder::ORDER_STATUS_FAILED, + ]; + $workings = [ + sOrder::ORDER_STATUS_PROCESSING, + sOrder::ORDER_STATUS_CONFIRMED, + sOrder::ORDER_STATUS_PACKING, + sOrder::ORDER_STATUS_READY_FOR_SHIPMENT, + sOrder::ORDER_STATUS_SHIPPED, + sOrder::ORDER_STATUS_DELIVERED, + sOrder::ORDER_STATUS_ON_HOLD, + sOrder::ORDER_STATUS_RETURN_REQUESTED, + ]; + $completeds = [ + sOrder::ORDER_STATUS_DELETED, + sOrder::ORDER_STATUS_COMPLETED, + sOrder::ORDER_STATUS_CANCELED, + sOrder::ORDER_STATUS_RETURNED, + ]; + + $data['items'] = $query->paginate($perpage); + $data['unprocessedes'] = $unprocessedes; + $data['workings'] = $workings; + $data['completeds'] = $completeds; + $data['status'] = $status; + $data['statuses'] = array_intersect_key(sOrder::listOrderStatuses(), $dbStatuses); + $data['total'] = sOrder::count(); + $data['unprocessed'] = sOrder::whereIn('status', $unprocessedes)->count(); + $data['working'] = sOrder::whereIn('status', $workings)->count(); + $data['completed'] = sOrder::whereIn('status', $completeds)->count(); + $_SESSION['itemaction'] = 'Viewing a list of orders'; + $_SESSION['itemname'] = __('sCommerce::global.title'); + break; + case "order": + $tabs = ['order']; + $iUrl = trim($iUrl) ?: '&i=0'; + $requestId = (int)request()->input('i', 0); + $item = sOrder::find($requestId); + + $unprocessedes = [ + sOrder::ORDER_STATUS_NEW, + sOrder::ORDER_STATUS_FAILED, + ]; + $workings = [ + sOrder::ORDER_STATUS_PROCESSING, + sOrder::ORDER_STATUS_CONFIRMED, + sOrder::ORDER_STATUS_PACKING, + sOrder::ORDER_STATUS_READY_FOR_SHIPMENT, + sOrder::ORDER_STATUS_SHIPPED, + sOrder::ORDER_STATUS_DELIVERED, + sOrder::ORDER_STATUS_ON_HOLD, + sOrder::ORDER_STATUS_RETURN_REQUESTED, + ]; + $completeds = [ + sOrder::ORDER_STATUS_DELETED, + sOrder::ORDER_STATUS_COMPLETED, + sOrder::ORDER_STATUS_CANCELED, + sOrder::ORDER_STATUS_RETURNED, + ]; + + $data['item'] = $item; + $data['unprocessedes'] = $unprocessedes; + $data['workings'] = $workings; + $data['completeds'] = $completeds; + $data['payment'] = isset($item->payment_info['method']) && trim($item->payment_info['method']) ? sCheckout::getPayment($item->payment_info['method']) : false; + $data['delivery'] = isset($item->delivery_info['method']) && trim($item->delivery_info['method']) ? sCheckout::getDelivery($item->delivery_info['method']) : false; + $_SESSION['itemaction'] = 'Editing a Order of #' . $item->id; + $_SESSION['itemname'] = __('sCommerce::global.title'); break; /* |-------------------------------------------------------------------------- diff --git a/src/Checkout/sCheckout.php b/src/Checkout/sCheckout.php index 0e133da..4b58e0c 100644 --- a/src/Checkout/sCheckout.php +++ b/src/Checkout/sCheckout.php @@ -480,8 +480,8 @@ public static function quickOrder(array $data) $userData = [ 'id' => $user['id'] ?? 0, 'name' => $user['fullname'] ?? '', - 'email' => $user['email'] ?? ($data['email'] ?? ''), - 'phone' => $user['phone'] ?? ($data['phone'] ?? ''), + 'email' => $data['email'] ?? ($user['email'] ?? ''), + 'phone' => $data['phone'] ?? ($user['phone'] ?? ''), 'address' => [ 'country' => $user['country'] ?? '', 'state' => $user['state'] ?? '', @@ -538,22 +538,30 @@ public static function quickOrder(array $data) $adminNotes = [ [ 'comment' => "Quick order created by user " . implode(' ', [trim($userData['name']), trim($userData['phone']), trim($userData['email'])]) . '.', - 'timestamp' => now(), + 'timestamp' => now()->toDateTimeString(), 'user_id' => (int)$userData['id'], ] ]; + $history = [ + [ + 'status' => sOrder::ORDER_STATUS_NEW, + 'timestamp' => now()->toDateTimeString(), + 'user_id' => 0, + ] + ]; + $order = new sOrder(); $order->user_id = (int)$userData['id']; $order->identifier = $identifier; - $order->user_info = json_encode($userData, JSON_UNESCAPED_UNICODE); - $order->products = json_encode($productsData, JSON_UNESCAPED_UNICODE); + $order->user_info = $userData; + $order->products = $productsData; $order->cost = $cost; $order->currency = sCommerce::currentCurrency(); + $order->lang = evo()->getLocale(); $order->is_quick = true; - $order->admin_notes = json_encode([ - 'purchase_link' => back()->getTargetUrl(), - ], JSON_UNESCAPED_UNICODE); + $order->admin_notes = $adminNotes; + $order->history = $history; $order->save(); if ($data['productId'] == 0) { @@ -670,19 +678,28 @@ protected function saveOrder(): sOrder $identifier = Str::random(rand(32, 64)); } while (sOrder::where('identifier', $identifier)->exists()); + $history = [ + [ + 'status' => sOrder::ORDER_STATUS_NEW, + 'timestamp' => now()->toDateTimeString(), + 'user_id' => 0, + ] + ]; + $order = new sOrder(); $order->user_id = $this->orderData['user']['id'] ?? 0; - $order->user_info = json_encode(($this->orderData['user'] ?? []), JSON_UNESCAPED_UNICODE); - $order->delivery_info = json_encode(($this->orderData['delivery'] ?? []), JSON_UNESCAPED_UNICODE); - $order->payment_info = json_encode(($this->orderData['payment'] ?? []), JSON_UNESCAPED_UNICODE); - $order->products = json_encode(($this->orderData['products'] ?? []), JSON_UNESCAPED_UNICODE); - $order->cost = $this->orderData['cost']; + $order->user_info = $this->orderData['user'] ?? []; + $order->delivery_info = $this->orderData['delivery'] ?? []; + $order->payment_info = $this->orderData['payment'] ?? []; + $order->products = $this->orderData['products'] ?? []; + $order->cost = $this->orderData['cost'] ?? 0; $order->currency = $this->orderData['currency'] ?? sCommerce::currentCurrency(); $order->status = sOrder::ORDER_STATUS_NEW; $order->do_not_call = intval($this->orderData['do_not_call'] ?? 0); $order->comment = $this->orderData['comment'] ?? ''; $order->lang = evo()->getLocale(); $order->identifier = $identifier; + $order->history = $history; $order->save(); return $order; diff --git a/src/Models/sOrder.php b/src/Models/sOrder.php index 46d13b7..81c1371 100644 --- a/src/Models/sOrder.php +++ b/src/Models/sOrder.php @@ -63,6 +63,7 @@ class sOrder extends Model 'payment_info' => 'array', 'products' => 'array', 'admin_notes' => 'array', + 'history' => 'array', 'do_not_call' => 'boolean', ]; diff --git a/views/orderTab.blade.php b/views/orderTab.blade.php new file mode 100644 index 0000000..84361e7 --- /dev/null +++ b/views/orderTab.blade.php @@ -0,0 +1,178 @@ +@php use Seiger\sCommerce\Models\sOrder; @endphp +

+ @lang('sCommerce::global.order') #{{$item->id}} + @if($item->is_quick) @lang('sCommerce::global.one_click')@endif + {{$item->user_info['name']}} {{$item->user_info['phone']}} +

+

+

+ @lang('sCommerce::global.created'): {{$item->created_at}} + in_array($item->status, $unprocessedes), 'bg-progress' => in_array($item->status, $workings), 'bg-disactive' => in_array($item->status, $completeds)])> + {{sOrder::getOrderStatusName($item->status)}} + +

+

+ @lang('sCommerce::global.sum'): {{sCommerce::convertPrice($item->cost, $item->currency)}} + $item->payment_status == sOrder::PAYMENT_STATUS_PAID, 'bg-pending' => $item->payment_status != sOrder::PAYMENT_STATUS_PAID])>{{sOrder::getPaymentStatusName($item->payment_status)}} +

+
+ +
+ + +

@lang('sCommerce::global.payment_information')

+

+

@lang('sCommerce::global.order_currency'): {{$item->currency}}

+

@lang('sCommerce::global.order_cost'): {{$item->cost}}

+

@lang('sCommerce::global.payment_name'):@if(!$payment) @lang('sCommerce::global.not_selected_or_unknown') @else {{$payment['title']}}@endif

+

+ @lang('sCommerce::global.payment_status'): + +

+
+ +

@lang('sCommerce::global.order_status_management')

+

+ @lang('sCommerce::global.order_status'): + +

+
+ +

@lang('sCommerce::global.products_in_order')

+ + + + + + + + + + + @foreach($item->products as $product) + @php($info = '') + @foreach($product as $p) + @if(is_array($p) && isset($p['title'])) + @php($info .= '' . htmlentities($p['title']) . ': ' . htmlentities($p['label'] ?? '') . '
') + @endif + @endforeach + + + + + + + @endforeach + +
@lang('sCommerce::global.product_name')@lang('sCommerce::global.price')@lang('sCommerce::global.quantity')@lang('sCommerce::global.sum')
+ + {{$product['title']}} + @if(trim($info))@endif + {{$product['price']}}{{$product['quantity']}}{{sCommerce::convertPrice($product['quantity'] * sCommerce::convertPriceNumber($product['price'], $item->currency, $item->currency), $item->currency)}}
+
+ +

@lang('sCommerce::global.shipping_information')

+

@lang('sCommerce::global.delivery_name'):@if(!$delivery) @lang('sCommerce::global.not_selected_or_unknown') @else {{$delivery['title']}}@endif

+ @if($delivery) +

@lang('sCommerce::global.shipping_cost'): {{sCommerce::convertPrice(floatval($item->delivery_info['cost'] ?? 0), $item->currency)}}

+ @if(is_array($item->delivery_info[$item->delivery_info['method']])) + @foreach($item->delivery_info[$item->delivery_info['method']] as $key => $value) +

{{$key}}: {{$value}}

+ @endforeach + @endif + @endif +
+ +

@lang('sCommerce::global.customer_information')

+

+ @lang('global.user_full_name'): + @if((int)$item->user_info['id'] > 0) + {{$item->user_info['name'] ?? ''}} + @else + {{$item->user_info['name'] ?? ''}} + @endif +

+

@lang('global.user_phone'): {{$item->user_info['phone'] ?? ''}}

+

@lang('global.user_email'): {{$item->user_info['email'] ?? ''}}

+
+ +

@lang('sCommerce::global.comments_and_notes')

+ + @foreach($item->admin_notes as $note) +

+ {{$note['timestamp'] ?? ''}}: + @if((int)$note['user_id'] > 0) + {{evo()->getUserInfo((int)$note['user_id'])['username']}} + @else + @lang('sCommerce::global.system') + @endif +

+

{!!$note['comment']!!}

+ @endforeach +
+
+ +
+

@lang('sCommerce::global.history_changes')

+ + + + + + + + + + @foreach($item->history as $history) + + + + + + @endforeach + +
@lang('global.mgrlog_time')@lang('sCommerce::global.status')@lang('global.mgrlog_user')
{{$history['timestamp'] ?? ''}} + in_array((int)$history['status'], $unprocessedes), 'bg-progress' => in_array((int)$history['status'], $workings), 'bg-disactive' => in_array((int)$history['status'], $completeds)])> + {{sOrder::getOrderStatusName($item->status)}} + + + @if((int)$history['user_id'] > 0) + {{evo()->getUserInfo((int)$history['user_id'])['username']}} + @else + @lang('sCommerce::global.system') + @endif +
+
+ + + +@push('scripts.bot') +
+
+ + @lang('sCommerce::global.to_list_orders') + + + + @lang('global.save') + +
+
+@endpush diff --git a/views/ordersTab.blade.php b/views/ordersTab.blade.php new file mode 100644 index 0000000..7fe70cc --- /dev/null +++ b/views/ordersTab.blade.php @@ -0,0 +1,133 @@ +@php use Seiger\sCommerce\Models\sOrder; @endphp +@php($order = request()->has('order') ? request()->input('order') : 'id') + +
+
+
+
@lang('sCommerce::global.total_orders'): {{$total ?? 0}}
+
@lang('sCommerce::global.unprocessed_orders'): {{$unprocessed ?? 0}}
+
@lang('sCommerce::global.working_orders'): {{$working ?? 0}}
+
@lang('sCommerce::global.completed_orders'): {{$completed ?? 0}}
+
+
+
+ + + + + + +
+ +
+
+
+
+ $status == 0, 'btn-light' => $status != 0]) href="{!!sCommerce::moduleUrl()!!}&get=orders" class="btn btn-info">@lang('sCommerce::global.all_statuses') + @foreach($statuses as $id => $name) + $status == $id, 'btn-light' => $status != $id]) href="{!!sCommerce::moduleUrl()!!}&get=orders&status={{$id}}">{{$name}} + @endforeach +
+
+ + + + + + + + + + + + + + @foreach($items as $item) + + + + + + + + + + @endforeach + +
+ + + + + + + + + + + + @lang('global.onlineusers_action')
#{{$item->id}}@if($item->is_quick) @lang('sCommerce::global.one_click')@endif{{$item->client}} {{$item->user_info['phone'] ?? ''}}{{$item->created_at}}{{sCommerce::convertPrice($item->cost, $item->currency)}}{{sOrder::getPaymentStatusName($item->payment_status)}}{{sOrder::getOrderStatusName($item->status)}} + +
+
+
+
+
{{$items->render()}}
+
+ @lang('sCommerce::global.items_on_page') + +
+
+@push('scripts.top') + +@endpush \ No newline at end of file diff --git a/views/partials/style.blade.php b/views/partials/style.blade.php index c27df5f..830f413 100644 --- a/views/partials/style.blade.php +++ b/views/partials/style.blade.php @@ -17,6 +17,11 @@ .alertify .ajs-footer .ajs-buttons .ajs-button.ajs-ok-info{color:#fff;background-color:#5bc0de;border-color:#5bc0de;} .alertify .ajs-footer .ajs-buttons .ajs-button.ajs-ok-blue{color:#fff;background-color:#0275d8;border-color:#0275d8;} .badge.bg-seigerit{background-color:#0057b8 !important;color:#ffd700;font-size:85%;} + .badge.bg-active{background-color:var(--brand-green, #009891) !important;color:#fff;font-size:90%;} + .badge.bg-disactive{background-color:var(--brand-pink, #EF4B67) !important;color:#fff;font-size:90%;} + .badge.bg-progress{background-color:var(--brand-orange, #fd7e14) !important;color:#fff;font-size:90%;} + .badge.bg-pending{background-color:var(--brand-red, #d9534f) !important;color:#fff;font-size:90%;} + .badge.bg-paid{background-color:var(--brand-green, #28a745) !important;color:#fff;font-size:90%;} .badge.bg-super{vertical-align:super;font-size:60% !important;} .builder .row{display:flex;flex-wrap:wrap;margin-left:-.25rem;margin-right:-.25rem;cursor:default} .builder .col-4, .builder .col-8, .builder .col-12, .builder .col, .builder .col-auto{position:relative;width:100%;min-height:0;padding-left:.25rem;padding-right:.25rem} @@ -54,6 +59,7 @@ .scom-all{color:var(--text-text-base, #0D0D0D);font-size:16px;font-weight:700;line-height:120%;} .scom-active{color:var(--brand-green, #009891);} .scom-disactive{color:var(--brand-pink, #EF4B67);} + .scom-progress{color:var(--brand-orange, #fd7e14);} .form-control.scom-input{height:42px;font-weight:400;line-height:120%;padding:16px 12px;} .scom-btn-container{display:flex;flex-flow:row wrap;justify-content:space-between;gap:5px;} .scom-btn-container .btn:last-child {margin-right: auto;}