mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-17 06:52:27 +01:00
(quality) compute withdrawal instructions server side
This commit is contained in:
parent
185b4f1459
commit
0464aae23e
@ -25,6 +25,17 @@ class API::OrdersController < API::ApiController
|
||||
head :no_content
|
||||
end
|
||||
|
||||
def withdrawal_instructions
|
||||
begin
|
||||
order = Order.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
order = nil
|
||||
end
|
||||
authorize order || Order
|
||||
|
||||
render html: ::Orders::OrderService.withdrawal_instructions(order)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_order
|
||||
|
@ -18,4 +18,9 @@ export default class OrderAPI {
|
||||
const res: AxiosResponse<Order> = await apiClient.patch(`/api/orders/${order.id}`, { order: { state, note } });
|
||||
return res?.data;
|
||||
}
|
||||
|
||||
static async withdrawalInstructions (order?: Order): Promise<string> {
|
||||
const res: AxiosResponse<string> = await apiClient.get(`/api/orders/${order?.id}/withdrawal_instructions`);
|
||||
return res?.data;
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,8 @@ import noImage from '../../../../images/no_image.png';
|
||||
import Switch from 'react-switch';
|
||||
import OrderLib from '../../lib/order';
|
||||
import { CaretDown, CaretUp } from 'phosphor-react';
|
||||
import SettingAPI from '../../api/setting';
|
||||
import { SettingName } from '../../models/setting';
|
||||
import _ from 'lodash';
|
||||
import OrderAPI from '../../api/order';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -41,11 +40,11 @@ const StoreCart: React.FC<StoreCartProps> = ({ onSuccess, onError, currentUser,
|
||||
const [cartErrors, setCartErrors] = useState<OrderErrors>(null);
|
||||
const [noMemberError, setNoMemberError] = useState<boolean>(false);
|
||||
const [paymentModal, setPaymentModal] = useState<boolean>(false);
|
||||
const [settings, setSettings] = useState<Map<SettingName, string>>(null);
|
||||
const [withdrawalInstructions, setWithdrawalInstructions] = useState<string>(null);
|
||||
|
||||
useEffect(() => {
|
||||
SettingAPI.query(['store_withdrawal_instructions', 'fablab_name'])
|
||||
.then(res => setSettings(res))
|
||||
OrderAPI.withdrawalInstructions(cart)
|
||||
.then(setWithdrawalInstructions)
|
||||
.catch(onError);
|
||||
}, []);
|
||||
|
||||
@ -244,17 +243,6 @@ const StoreCart: React.FC<StoreCartProps> = ({ onSuccess, onError, currentUser,
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Text instructions for the customer
|
||||
*/
|
||||
const withdrawalInstructions = (): string => {
|
||||
const instructions = settings?.get('store_withdrawal_instructions');
|
||||
if (!_.isEmpty(instructions)) {
|
||||
return instructions;
|
||||
}
|
||||
return t('app.public.store_cart.please_contact_FABLAB', { FABLAB: settings?.get('fablab_name') });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='store-cart'>
|
||||
<div className="store-cart-list">
|
||||
@ -319,7 +307,7 @@ const StoreCart: React.FC<StoreCartProps> = ({ onSuccess, onError, currentUser,
|
||||
<div className="group">
|
||||
<div className='store-cart-info'>
|
||||
<h3>{t('app.public.store_cart.pickup')}</h3>
|
||||
<p dangerouslySetInnerHTML={{ __html: withdrawalInstructions() }} />
|
||||
<p dangerouslySetInnerHTML={{ __html: withdrawalInstructions }} />
|
||||
</div>
|
||||
|
||||
{cart && !cartIsEmpty() &&
|
||||
|
@ -50,13 +50,13 @@ export const OrderItem: React.FC<OrderItemProps> = ({ order, currentUser }) => {
|
||||
<span>{t('app.shared.store.order_item.created_at')}</span>
|
||||
<div>
|
||||
<p>{FormatLib.date(order.created_at)}
|
||||
<div className="fab-tooltip">
|
||||
<span className="fab-tooltip">
|
||||
<span className="trigger"><PlusCircle size={16} weight="light" /></span>
|
||||
<div className="content">
|
||||
<span className="content">
|
||||
{t('app.shared.store.order_item.last_update')}<br />
|
||||
{FormatLib.date(order.updated_at)}
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import _ from 'lodash';
|
||||
import { IApplication } from '../../models/application';
|
||||
import { User } from '../../models/user';
|
||||
import { react2angular } from 'react2angular';
|
||||
@ -12,8 +11,6 @@ import { Order } from '../../models/order';
|
||||
import FormatLib from '../../lib/format';
|
||||
import OrderLib from '../../lib/order';
|
||||
import { OrderActions } from './order-actions';
|
||||
import SettingAPI from '../../api/setting';
|
||||
import { SettingName } from '../../models/setting';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -31,17 +28,20 @@ export const ShowOrder: React.FC<ShowOrderProps> = ({ orderId, currentUser, onSu
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
const [order, setOrder] = useState<Order>();
|
||||
const [settings, setSettings] = useState<Map<SettingName, string>>(null);
|
||||
const [withdrawalInstructions, setWithdrawalInstructions] = useState<string>(null);
|
||||
|
||||
useEffect(() => {
|
||||
OrderAPI.get(orderId).then(data => {
|
||||
setOrder(data);
|
||||
}).catch(onError);
|
||||
SettingAPI.query(['store_withdrawal_instructions', 'fablab_name'])
|
||||
.then(res => setSettings(res))
|
||||
.catch(onError);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
OrderAPI.withdrawalInstructions(order)
|
||||
.then(setWithdrawalInstructions)
|
||||
.catch(onError);
|
||||
}, [order]);
|
||||
|
||||
/**
|
||||
* Check if the current operator has administrative rights or is a normal member
|
||||
*/
|
||||
@ -79,17 +79,6 @@ export const ShowOrder: React.FC<ShowOrderProps> = ({ orderId, currentUser, onSu
|
||||
return paymentVerbose;
|
||||
};
|
||||
|
||||
/**
|
||||
* Text instructions for the customer
|
||||
*/
|
||||
const withdrawalInstructions = (): string => {
|
||||
const instructions = settings?.get('store_withdrawal_instructions');
|
||||
if (!_.isEmpty(instructions)) {
|
||||
return instructions;
|
||||
}
|
||||
return t('app.shared.store.show_order.please_contact_FABLAB', { FABLAB: settings?.get('fablab_name') });
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback after action success
|
||||
*/
|
||||
@ -202,7 +191,7 @@ export const ShowOrder: React.FC<ShowOrderProps> = ({ orderId, currentUser, onSu
|
||||
</div>
|
||||
<div className="withdrawal-instructions">
|
||||
<label>{t('app.shared.store.show_order.pickup')}</label>
|
||||
<p dangerouslySetInnerHTML={{ __html: withdrawalInstructions() }} />
|
||||
<p dangerouslySetInnerHTML={{ __html: withdrawalInstructions }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,4 +13,8 @@ class OrderPolicy < ApplicationPolicy
|
||||
def destroy?
|
||||
user.privileged?
|
||||
end
|
||||
|
||||
def withdrawal_instructions?
|
||||
user.privileged? || (record&.statistic_profile_id == user.statistic_profile.id)
|
||||
end
|
||||
end
|
||||
|
@ -3,6 +3,8 @@
|
||||
# Provides methods for Order
|
||||
class Orders::OrderService
|
||||
class << self
|
||||
include ApplicationHelper
|
||||
|
||||
ORDERS_PER_PAGE = 20
|
||||
|
||||
def list(filters, current_user)
|
||||
@ -71,6 +73,14 @@ class Orders::OrderService
|
||||
true
|
||||
end
|
||||
|
||||
def withdrawal_instructions(order)
|
||||
res = order&.order_activities&.find_by(activity_type: 'ready')&.note.presence ||
|
||||
Setting.get('store_withdrawal_instructions').presence ||
|
||||
_t('order.please_contact_FABLAB', FABLAB: Setting.get('fablab_name').presence || 'empty')
|
||||
|
||||
ActionController::Base.helpers.sanitize(res, tags: %w[p ul li h3 u em strong a], attributes: %w[target rel href])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filter_by_user(orders, filters, current_user)
|
||||
|
@ -4,5 +4,5 @@
|
||||
<%= t('.body.notify_user_order_is_ready', REFERENCE: @attached_object.order.reference) %>
|
||||
</p>
|
||||
<p>
|
||||
<%= sanitize @attached_object.note.presence || Setting.get('store_withdrawal_istructions').presence || _t('notify_user_order_is_ready.body.please_contact_FABLAB', FABLAB: Setting.get('fablab_name')) %>
|
||||
<%= ::Orders::OrderService.withdrawal_instructions(@attached_object.order) %>
|
||||
</p>
|
||||
|
@ -442,7 +442,6 @@ en:
|
||||
checkout_error: "An unexpected error occurred. Please contact the administrator."
|
||||
checkout_success: "Purchase confirmed. Thanks!"
|
||||
select_user: "Please select a user before continuing."
|
||||
please_contact_FABLAB: "Please contact {FABLAB, select, undefined{us} other{{FABLAB}}} for withdrawal instructions."
|
||||
update_item: "Update"
|
||||
errors:
|
||||
product_not_found: "This product is no longer available, please remove it from your cart."
|
||||
|
@ -593,7 +593,6 @@ en:
|
||||
coupon: "Coupon"
|
||||
cart_total: "Cart total"
|
||||
pickup: "Pickup your products"
|
||||
please_contact_FABLAB: "Please contact {FABLAB, select, undefined{us} other{{FABLAB}}} for withdrawal instructions."
|
||||
state:
|
||||
cart: 'Cart'
|
||||
in_progress: 'Under preparation'
|
||||
@ -623,12 +622,12 @@ en:
|
||||
delivered: "Delivered"
|
||||
confirm: 'Confirm'
|
||||
confirmation_required: "Confirmation required"
|
||||
confirm_order_in_progress_html: "Please confirm this order in being prepared."
|
||||
confirm_order_in_progress_html: "Please confirm that this order in being prepared."
|
||||
order_in_progress_success: "Order is under preparation"
|
||||
confirm_order_ready_html: "Please confirm this order is ready."
|
||||
confirm_order_ready_html: "Please confirm that this order is ready."
|
||||
order_ready_note: 'You can leave a message to the customer about withdrawal instructions'
|
||||
order_ready_success: "Order is ready"
|
||||
confirm_order_delivered_html: "Please confirm this order was delivered."
|
||||
confirm_order_delivered_html: "Please confirm that this order was delivered."
|
||||
order_delivered_success: "Order was delivered"
|
||||
confirm_order_canceled_html: "<strong>Do you really want to cancel this order?</strong><p>If this impacts stock, please reflect the change in <em>edit product > stock management</em>. This won't be automatic.</p>"
|
||||
order_canceled_success: "Order was canceled"
|
||||
|
@ -44,8 +44,8 @@ en:
|
||||
registration_disabled: "Registration is disabled"
|
||||
undefined_in_store: "must be defined to make the product available in the store"
|
||||
gateway_error: "Payement gateway error: %{MESSAGE}"
|
||||
gateway_amount_too_small: "Payments under %{AMOUNT} are not supported. Please contact reception directly."
|
||||
gateway_amount_too_large: "Payments above %{AMOUNT} are not supported. Please contact reception directly."
|
||||
gateway_amount_too_small: "Payments under %{AMOUNT} are not supported. Please order directly at the reception."
|
||||
gateway_amount_too_large: "Payments above %{AMOUNT} are not supported. Please order directly at the reception."
|
||||
apipie:
|
||||
api_documentation: "API Documentation"
|
||||
code: "HTTP code"
|
||||
@ -475,6 +475,8 @@ en:
|
||||
free_extension: "Free extension of a subscription, until %{DATE}"
|
||||
statistic_profile:
|
||||
birthday_in_past: "The date of birth must be in the past"
|
||||
order:
|
||||
please_contact_FABLAB: "Please contact {FABLAB, select, nil{us} other{{FABLAB}}} for withdrawal instructions."
|
||||
settings:
|
||||
locked_setting: "the setting is locked."
|
||||
about_title: "\"About\" page title"
|
||||
|
@ -378,12 +378,11 @@ en:
|
||||
subject: "Your command is ready"
|
||||
body:
|
||||
notify_user_order_is_ready: "Your command %{REFERENCE} is ready:"
|
||||
please_contact_FABLAB: "Please contact {FABLAB, select, undefined{us} other{{FABLAB}}} for withdrawal instructions."
|
||||
notify_user_order_is_canceled:
|
||||
subject: "Your command is canceled"
|
||||
subject: "Your command was canceled"
|
||||
body:
|
||||
notify_user_order_is_canceled: "Your command %{REFERENCE} is canceled."
|
||||
notify_user_order_is_canceled: "Your command %{REFERENCE} was canceled."
|
||||
notify_user_order_is_refunded:
|
||||
subject: "Your command is refunded"
|
||||
subject: "Your command was refunded"
|
||||
body:
|
||||
notify_user_order_is_refunded: "Your command %{REFERENCE} is refunded:"
|
||||
notify_user_order_is_refunded: "Your command %{REFERENCE} was refunded."
|
||||
|
@ -169,7 +169,9 @@ Rails.application.routes.draw do
|
||||
post 'payment', on: :collection
|
||||
post 'confirm_payment', on: :collection
|
||||
end
|
||||
resources :orders, except: %i[create]
|
||||
resources :orders, except: %i[create] do
|
||||
get 'withdrawal_instructions', on: :member
|
||||
end
|
||||
|
||||
# for admin
|
||||
resources :trainings do
|
||||
|
Loading…
x
Reference in New Issue
Block a user