Skip to content

Commit

Permalink
feat: add split lines on customer delivery (#842)
Browse files Browse the repository at this point in the history
* RM#88324
  • Loading branch information
vhu-axelor authored Dec 20, 2024
1 parent 91317fe commit 2b5d02b
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 47 deletions.
5 changes: 5 additions & 0 deletions changelogs/unreleased/88324.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "Customer delivery: add button to split lines",
"type": "feat",
"packages": "stock"
}
9 changes: 9 additions & 0 deletions packages/apps/stock/src/api/customer-delivery-line-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,12 @@ export async function fetchCustomerDeliveryLine({customerDeliveryLineId}) {
provider: 'model',
});
}

export async function splitCustomerDeliveryLine({id, version}) {
return getActionApi().send({
url: `ws/aos/stock-move-line/split/${id}`,
method: 'put',
body: {version},
description: 'split customer delivery line',
});
}
3 changes: 2 additions & 1 deletion packages/apps/stock/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ export {
searchDeliveryFilter,
} from './customer-delivery-api';
export {
fetchCustomerDeliveryLine as fetchCustomerDeliveryLineApi,
searchCustomerDeliveryLines,
splitCustomerDeliveryLine as splitCustomerDeliveryLineApi,
updateLine as updateCustomerDeliveryLineApi,
fetchCustomerDeliveryLine as fetchCustomerDeliveryLineApi,
} from './customer-delivery-line-api';
export {
createInternalStockMove,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Axelor Business Solutions
*
* Copyright (C) 2024 Axelor (<http://axelor.com>).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React, {useCallback, useMemo} from 'react';
import {ActionCard} from '@axelor/aos-mobile-ui';
import {
useDispatch,
useSelector,
useTranslator,
useTypes,
} from '@axelor/aos-mobile-core';
import {StockMoveLine} from '../../../../types';
import {splitCustomerDeliveryLine} from '../../../../features/customerDeliveryLineSlice';
import CustomerDeliveryLineCard from '../CustomerDeliveryLineCard/CustomerDeliveryLineCard';

interface CustomerDeliveryLineActionCardProps {
style?: any;
styleCard?: any;
customerDeliveryLine: any;
handleShowLine: (customerDeliveryLine: any) => void;
}

const CustomerDeliveryLineActionCard = ({
style,
styleCard,
customerDeliveryLine,
handleShowLine,
}: CustomerDeliveryLineActionCardProps) => {
const I18n = useTranslator();
const dispatch = useDispatch();
const {StockMove} = useTypes();

const {customerDelivery} = useSelector(state => state.customerDelivery);

const splitCustomerDeliveryLineAPI = useCallback(() => {
dispatch(
(splitCustomerDeliveryLine as any)({
id: customerDeliveryLine.id,
version: customerDeliveryLine.version,
customerDeliveryId: customerDelivery?.id,
}),
);
}, [
dispatch,
customerDeliveryLine.id,
customerDeliveryLine.version,
customerDelivery?.id,
]);

const pickedQty = useMemo(
() =>
StockMoveLine.hideLineQty(customerDeliveryLine, customerDelivery)
? 0
: Number(customerDeliveryLine.realQty),
[customerDelivery, customerDeliveryLine],
);

const availability = useMemo(
() =>
customerDelivery.statusSelect !== StockMove?.statusSelect.Realized
? customerDeliveryLine.availableStatusSelect
: null,
[
StockMove?.statusSelect.Realized,
customerDelivery.statusSelect,
customerDeliveryLine.availableStatusSelect,
],
);

return (
<ActionCard
style={style}
translator={I18n.t}
actionList={[
{
iconName: 'diagram-2-fill',
helper: I18n.t('Stock_Split'),
onPress: splitCustomerDeliveryLineAPI,
hidden:
customerDelivery.statusSelect > StockMove?.statusSelect.Planned ||
pickedQty >= customerDeliveryLine.qty ||
pickedQty === 0,
},
]}>
<CustomerDeliveryLineCard
style={styleCard}
productName={customerDeliveryLine.product?.fullName}
stockLocationName={customerDeliveryLine.fromStockLocation?.name}
askedQty={customerDeliveryLine.qty}
pickedQty={pickedQty}
locker={customerDeliveryLine.locker}
availability={availability}
stockMoveLineId={customerDeliveryLine.id}
trackingNumber={customerDeliveryLine.trackingNumber}
onPress={() => handleShowLine(customerDeliveryLine)}
/>
</ActionCard>
);
};

export default CustomerDeliveryLineActionCard;
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ const getStyles = color =>
borderWidth: 1.5,
borderColor: color,
paddingRight: 5,
marginVertical: 2,
marginHorizontal: 2,
},
textWidth: {
width: '85%',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ import {
useTranslator,
useTypes,
} from '@axelor/aos-mobile-core';
import {CustomerDeliveryLineCard} from '../../../templates';
import {CustomerDeliveryLineActionCard} from '../../../templates';
import {SearchLineContainer} from '../../../organisms';
import {showLine} from '../../../../utils/line-navigation';
import {StockMoveLine} from '../../../../types';
import {fetchCustomerDeliveryLines} from '../../../../features/customerDeliveryLineSlice';
import {useCustomerLinesWithRacks} from '../../../../hooks';

Expand Down Expand Up @@ -138,33 +137,19 @@ const CustomerDeliverySearchLineContainer = ({}) => {
showAction={showLineAdditionIcon}
onAction={handleNewLine}
renderItem={item => (
<CustomerDeliveryLineCard
style={styles.item}
productName={item.product?.fullName}
stockLocationName={item.fromStockLocation?.name}
pickedQty={
StockMoveLine.hideLineQty(item, customerDelivery) ? 0 : item.realQty
}
askedQty={item.qty}
trackingNumber={item.trackingNumber}
locker={item.locker}
availability={
customerDelivery.statusSelect !== StockMove?.statusSelect.Realized
? item.availableStatusSelect
: null
}
stockMoveLineId={item.id}
onPress={() => handleShowLine(item)}
<CustomerDeliveryLineActionCard
style={styles.card}
customerDeliveryLine={item}
handleShowLine={handleShowLine}
/>
)}
/>
);
};

const styles = StyleSheet.create({
item: {
marginHorizontal: 1,
marginVertical: 4,
card: {
width: '100%',
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

export {default as CustomerDeliveryCard} from './CustomerDeliveryCard/CustomerDeliveryCard';
export {default as CustomerDeliveryHeader} from './CustomerDeliveryHeader/CustomerDeliveryHeader';
export {default as CustomerDeliveryLineActionCard} from './CustomerDeliveryLineActionCard/CustomerDeliveryLineActionCard';
export {default as CustomerDeliveryLineButtons} from './CustomerDeliveryLineButtons/CustomerDeliveryLineButtons';
export {default as CustomerDeliveryLineCard} from './CustomerDeliveryLineCard/CustomerDeliveryLineCard';
export {default as CustomerDeliveryLineCreationButton} from './CustomerDeliveryLineCreationButton/CustomerDeliveryLineCreationButton';
Expand Down
1 change: 1 addition & 0 deletions packages/apps/stock/src/features/asyncFunctions-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export {
addTrackingNumber as addTrackingNumberToCustomerDeliveryLine,
fetchCustomerDeliveryLine,
fetchCustomerDeliveryLines,
splitCustomerDeliveryLine,
updateCustomerDeliveryLine,
} from './customerDeliveryLineSlice';
export {
Expand Down
22 changes: 21 additions & 1 deletion packages/apps/stock/src/features/customerDeliveryLineSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import {
updateAgendaItems,
} from '@axelor/aos-mobile-core';
import {
fetchCustomerDeliveryLine as _fetchCustomerDeliveryLine,
searchCustomerDeliveryLines,
splitCustomerDeliveryLine as _splitCustomerDeliveryLine,
updateLine,
fetchCustomerDeliveryLine as _fetchCustomerDeliveryLine,
} from '../api/customer-delivery-line-api';
import {updateStockMoveLineTrackingNumber} from '../api/tracking-number-api';

Expand Down Expand Up @@ -97,6 +98,25 @@ export const addTrackingNumber = createAsyncThunk(
},
);

export const splitCustomerDeliveryLine = createAsyncThunk(
'stock_customerDeliveryLine/splitCustomerDeliveryLine',
async function (data, {getState, dispatch}) {
return handlerApiCall({
fetchFunction: _splitCustomerDeliveryLine,
data,
action: 'Stock_SliceAction_SplitCustomerDeliveryLine',
getState,
responseOptions: {showToast: true},
}).then(() => {
dispatch(
fetchCustomerDeliveryLines({
customerDeliveryId: data.customerDeliveryId,
}),
);
});
},
);

const initialState = {
loadingCDLinesList: false,
moreLoading: false,
Expand Down
3 changes: 2 additions & 1 deletion packages/apps/stock/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,6 @@
"Stock_SliceAction_FetchSaleOrderQtyIndicator": "fetch data of sale order quantity indicator",
"Stock_SliceAction_FetchPurchaseOrderQtyIndicator": "fetch data of purchase order quantity indicator",
"Stock_SliceAction_FetchAvailableStockIndicator": "fetch data of available stock indicator",
"Stock_SliceAction_SplitSupplierArrivalLine": "split supplier arrival line"
"Stock_SliceAction_SplitSupplierArrivalLine": "split supplier arrival line",
"Stock_SliceAction_SplitCustomerDeliveryLine": "split customer delivery line"
}
3 changes: 2 additions & 1 deletion packages/apps/stock/src/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,6 @@
"Stock_SliceAction_FetchSaleOrderQtyIndicator": "récupération des données de l'indicateur sur la quantité en commande client",
"Stock_SliceAction_FetchPurchaseOrderQtyIndicator": "récupération des données de l'indicateur sur la quantité en ordre d'achat",
"Stock_SliceAction_FetchAvailableStockIndicator": "récupération des données de l'indicateur sur le stock disponible",
"Stock_SliceAction_SplitSupplierArrivalLine": "séparation de la ligne de réception fournisseur"
"Stock_SliceAction_SplitSupplierArrivalLine": "séparation de la ligne de réception fournisseur",
"Stock_SliceAction_SplitCustomerDeliveryLine": "séparation de la ligne de livraison client"
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import {
SearchListView,
useSelector,
useTranslator,
useTypes,
} from '@axelor/aos-mobile-core';
import {CustomerDeliveryLineCard, StockMoveHeader} from '../../components';
import {
CustomerDeliveryLineActionCard,
StockMoveHeader,
} from '../../components';
import {fetchCustomerDeliveryLines} from '../../features/customerDeliveryLineSlice';
import {StockMove as StockMoveType, StockMoveLine} from '../../types';
import {showLine} from '../../utils/line-navigation';
Expand All @@ -37,7 +39,6 @@ const CustomerDeliveryLineListScreen = ({route, navigation}) => {
const customerDelivery = route.params.customerDelivery;
const Colors = useThemeColor();
const I18n = useTranslator();
const {StockMove} = useTypes();

const {mobileSettings} = useSelector(state => state.appConfig);
const {customerDeliveryLineList} =
Expand Down Expand Up @@ -140,24 +141,9 @@ const CustomerDeliveryLineListScreen = ({route, navigation}) => {
/>
}
renderListItem={({item}) => (
<CustomerDeliveryLineCard
productName={item.product.fullName}
stockLocationName={item.fromStockLocation?.name}
pickedQty={
StockMoveLine.hideLineQty(item, customerDelivery)
? 0
: item.realQty
}
askedQty={item.qty}
trackingNumber={item?.trackingNumber}
locker={item.locker}
availability={
customerDelivery.statusSelect === StockMove?.statusSelect.Realized
? null
: item.availableStatusSelect
}
stockMoveLineId={item.id}
onPress={() => handleShowLine(item)}
<CustomerDeliveryLineActionCard
customerDeliveryLine={item}
handleShowLine={handleShowLine}
/>
)}
/>
Expand Down

0 comments on commit 2b5d02b

Please sign in to comment.