mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-30 19:52:20 +01:00
(bug) product stock status and quantity min to cart
This commit is contained in:
parent
6fc0b935d9
commit
8c75b5fdd4
@ -1,6 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { react2angular } from 'react2angular';
|
import { react2angular } from 'react2angular';
|
||||||
|
import _ from 'lodash';
|
||||||
import { Loader } from '../base/loader';
|
import { Loader } from '../base/loader';
|
||||||
import { IApplication } from '../../models/application';
|
import { IApplication } from '../../models/application';
|
||||||
import { FabButton } from '../base/fab-button';
|
import { FabButton } from '../base/fab-button';
|
||||||
@ -151,7 +152,7 @@ const StoreCart: React.FC<StoreCartProps> = ({ onSuccess, onError, currentUser,
|
|||||||
<span>/ {t('app.public.store_cart.unit')}</span>
|
<span>/ {t('app.public.store_cart.unit')}</span>
|
||||||
</div>
|
</div>
|
||||||
<select value={item.quantity} onChange={changeProductQuantity(item)}>
|
<select value={item.quantity} onChange={changeProductQuantity(item)}>
|
||||||
{Array.from({ length: 100 }, (_, i) => i + item.quantity_min).map(v => (
|
{_.range(item.quantity_min, item.orderable_external_stock + 1, 1).map(v => (
|
||||||
<option key={v} value={v}>{v}</option>
|
<option key={v} value={v}>{v}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
|
@ -49,7 +49,7 @@ export const ProductItem: React.FC<ProductItemProps> = ({ product, onEdit, onDel
|
|||||||
* Returns CSS class from stock status
|
* Returns CSS class from stock status
|
||||||
*/
|
*/
|
||||||
const statusColor = (product: Product) => {
|
const statusColor = (product: Product) => {
|
||||||
if (product.stock.external === 0 && product.stock.internal === 0) {
|
if (product.stock.external < 1 && product.stock.internal < 1) {
|
||||||
return 'out-of-stock';
|
return 'out-of-stock';
|
||||||
}
|
}
|
||||||
if (product.low_stock_threshold && (product.stock.external < product.low_stock_threshold || product.stock.internal < product.low_stock_threshold)) {
|
if (product.low_stock_threshold && (product.stock.external < product.low_stock_threshold || product.stock.internal < product.low_stock_threshold)) {
|
||||||
|
@ -53,10 +53,10 @@ export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, car
|
|||||||
* Returns CSS class from stock status
|
* Returns CSS class from stock status
|
||||||
*/
|
*/
|
||||||
const statusColor = (product: Product) => {
|
const statusColor = (product: Product) => {
|
||||||
if (product.stock.external === 0 && product.stock.internal === 0) {
|
if (product.stock.external < (product.quantity_min || 1)) {
|
||||||
return 'out-of-stock';
|
return 'out-of-stock';
|
||||||
}
|
}
|
||||||
if (product.low_stock_alert) {
|
if (product.low_stock_threshold && product.stock.external < product.low_stock_threshold) {
|
||||||
return 'low';
|
return 'low';
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
@ -90,7 +90,7 @@ export const StoreProductItem: React.FC<StoreProductItemProps> = ({ product, car
|
|||||||
<FabStateLabel status={statusColor(product)}>
|
<FabStateLabel status={statusColor(product)}>
|
||||||
{productStockStatus(product)}
|
{productStockStatus(product)}
|
||||||
</FabStateLabel>
|
</FabStateLabel>
|
||||||
{product.stock.external > 0 &&
|
{product.stock.external > (product.quantity_min || 1) &&
|
||||||
<FabButton icon={<i className="fas fa-cart-arrow-down" />} className="main-action-btn" onClick={addProductToCart}>
|
<FabButton icon={<i className="fas fa-cart-arrow-down" />} className="main-action-btn" onClick={addProductToCart}>
|
||||||
{t('app.public.store_product_item.add')}
|
{t('app.public.store_product_item.add')}
|
||||||
</FabButton>
|
</FabButton>
|
||||||
|
@ -68,10 +68,10 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, current
|
|||||||
* Returns CSS class from stock status
|
* Returns CSS class from stock status
|
||||||
*/
|
*/
|
||||||
const statusColor = (product: Product) => {
|
const statusColor = (product: Product) => {
|
||||||
if (product.stock.external === 0 && product.stock.internal === 0) {
|
if (product.stock.external < (product.quantity_min || 1)) {
|
||||||
return 'out-of-stock';
|
return 'out-of-stock';
|
||||||
}
|
}
|
||||||
if (product.low_stock_alert) {
|
if (product.low_stock_threshold && product.stock.external < product.low_stock_threshold) {
|
||||||
return 'low';
|
return 'low';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -80,7 +80,7 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, current
|
|||||||
* Return product's stock status
|
* Return product's stock status
|
||||||
*/
|
*/
|
||||||
const productStockStatus = (product: Product) => {
|
const productStockStatus = (product: Product) => {
|
||||||
if (product.stock.external === 0) {
|
if (product.stock.external < (product.quantity_min || 1)) {
|
||||||
return <span>{t('app.public.store_product_item.out_of_stock')}</span>;
|
return <span>{t('app.public.store_product_item.out_of_stock')}</span>;
|
||||||
}
|
}
|
||||||
if (product.low_stock_threshold && product.stock.external < product.low_stock_threshold) {
|
if (product.low_stock_threshold && product.stock.external < product.low_stock_threshold) {
|
||||||
@ -95,7 +95,9 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, current
|
|||||||
const setCount = (type: 'add' | 'remove') => {
|
const setCount = (type: 'add' | 'remove') => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'add':
|
case 'add':
|
||||||
setToCartCount(toCartCount + 1);
|
if (toCartCount < product.stock.external) {
|
||||||
|
setToCartCount(toCartCount + 1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'remove':
|
case 'remove':
|
||||||
if (toCartCount > product.quantity_min) {
|
if (toCartCount > product.quantity_min) {
|
||||||
@ -116,10 +118,12 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, current
|
|||||||
* Add product to cart
|
* Add product to cart
|
||||||
*/
|
*/
|
||||||
const addToCart = () => {
|
const addToCart = () => {
|
||||||
CartAPI.addItem(cart, product.id, toCartCount).then(data => {
|
if (toCartCount <= product.stock.external) {
|
||||||
setCart(data);
|
CartAPI.addItem(cart, product.id, toCartCount).then(data => {
|
||||||
onSuccess(t('app.public.store.add_to_cart_success'));
|
setCart(data);
|
||||||
}).catch(onError);
|
onSuccess(t('app.public.store.add_to_cart_success'));
|
||||||
|
}).catch(onError);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (product) {
|
if (product) {
|
||||||
@ -179,11 +183,13 @@ export const StoreProduct: React.FC<StoreProductProps> = ({ productSlug, current
|
|||||||
<p>{FormatLib.price(product.amount)} <sup>TTC</sup></p>
|
<p>{FormatLib.price(product.amount)} <sup>TTC</sup></p>
|
||||||
<span>/ {t('app.public.store_product_item.unit')}</span>
|
<span>/ {t('app.public.store_product_item.unit')}</span>
|
||||||
</div>
|
</div>
|
||||||
{product.stock.external > 0 &&
|
{product.stock.external > (product.quantity_min || 1) &&
|
||||||
<div className='to-cart'>
|
<div className='to-cart'>
|
||||||
<FabButton onClick={() => setCount('remove')} icon={<Minus size={16} />} className="minus" />
|
<FabButton onClick={() => setCount('remove')} icon={<Minus size={16} />} className="minus" />
|
||||||
<input type="number"
|
<input type="number"
|
||||||
value={toCartCount}
|
value={toCartCount}
|
||||||
|
min={product.quantity_min}
|
||||||
|
max={product.stock.external}
|
||||||
onChange={evt => typeCount(evt)} />
|
onChange={evt => typeCount(evt)} />
|
||||||
<FabButton onClick={() => setCount('add')} icon={<Plus size={16} />} className="plus" />
|
<FabButton onClick={() => setCount('add')} icon={<Plus size={16} />} className="plus" />
|
||||||
<FabButton onClick={() => addToCart()} icon={<i className="fas fa-cart-arrow-down" />}
|
<FabButton onClick={() => addToCart()} icon={<i className="fas fa-cart-arrow-down" />}
|
||||||
|
@ -32,6 +32,7 @@ export interface Order {
|
|||||||
orderable_name: string,
|
orderable_name: string,
|
||||||
orderable_ref?: string,
|
orderable_ref?: string,
|
||||||
orderable_main_image_url?: string,
|
orderable_main_image_url?: string,
|
||||||
|
orderable_external_stock: number,
|
||||||
quantity: number,
|
quantity: number,
|
||||||
quantity_min: number,
|
quantity_min: number,
|
||||||
amount: number,
|
amount: number,
|
||||||
|
@ -27,6 +27,7 @@ json.order_items_attributes order.order_items.order(created_at: :asc) do |item|
|
|||||||
json.orderable_name item.orderable.name
|
json.orderable_name item.orderable.name
|
||||||
json.orderable_ref item.orderable.sku
|
json.orderable_ref item.orderable.sku
|
||||||
json.orderable_main_image_url item.orderable.main_image&.attachment_url
|
json.orderable_main_image_url item.orderable.main_image&.attachment_url
|
||||||
|
json.orderable_external_stock item.orderable.stock['external']
|
||||||
json.quantity item.quantity
|
json.quantity item.quantity
|
||||||
json.quantity_min item.orderable.quantity_min
|
json.quantity_min item.orderable.quantity_min
|
||||||
json.amount item.amount / 100.0
|
json.amount item.amount / 100.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user