/**
* @file
* File : ordersSlice.js
* This file defines the orders slice for Redux state management.
* It provides the initial state, reducers, and actions to manage orders.
*
* @author Pierre-Yves Léglise <contact@axialdata.net>
* @name ordersSlice
*/
import { createSlice } from '@reduxjs/toolkit'
import { findDefaultOrdersGroupsStatus } from '../../utils/lib/findDefaultOrdersGroupsStatus'
/**
* The initial state for the orders slice.
* @type {OrdersState}
* @author Pierre-Yves Léglise <contact@axialdata.net>
* @typedef {Object} OrdersState * @author Pierre-Yves Léglise <contact@axialdata.net>
* @property {boolean} isLoading - Indicates if the data is currently being loaded.
* @property {string} currentOrdersGroupId - The ID of the currently selected orders group.
* @property {string} defaultOrdersGroupStatusId - The ID of the default orders group status.
* @property {string} error - Any error messages from failed operations.
* @property {Array} ordersGroups - A list of orders groups.
* @example
* const initialState = {
* isLoading: false,
* currentOrdersGroupId: '',
* defaultOrdersGroupStatusId: '',
* error: '',
* ordersGroups: [],
* }
* @returns {OrdersState} - The initial state for the orders slice.
*/
const initialState = {
isLoading: false,
currentOrdersGroupId: '',
defaultOrdersGroupStatusId: '',
error: '',
ordersGroups: [],
modalMatchInvoiceIsOpen: false,
modalSearchRefIsOpen: false,
orderSeletedFromEditRef: null,
matchingOrdersSelectedId: '',
}
/**
* Redux slice for managing the state of orders and order groups.
*/
const userSlice = createSlice({
name: 'orders',
initialState,
reducers: {
/**
* Resets the orders state to its initial state.
* @param {OrdersState} state - The current state of the orders.
*/
resetOrders: (state) => {
return initialState
},
/**
* Sets the loading state to true when an API call is pending.
* @param {OrdersState} state - The current state of the orders.
*/
ordersPending: (state) => {
state.isLoading = true
},
/**
* Sets the current orders group ID and clears any errors.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {string} action.payload - The ID of the orders group to set.
*/
setOrdersGroupId: (state, action) => {
state.isLoading = false
state.currentOrdersGroupId = action.payload
state.error = ''
},
/**
* Sets an error message and stops the loading state.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {string} action.payload - The error message.
*/
ordersError: (state, action) => {
state.isLoading = false
state.error = action.payload
},
/**
* Resets the current orders group ID and stops the loading state.
* @param {OrdersState} state - The current state of the orders.
*/
ordersQuit: (state) => {
state.isLoading = false
state.currentOrdersGroupId = ''
},
/**
* Sets the list of orders groups.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {Array} action.payload - The list of orders groups.
*/
setOrdersGroupsList: (state, action) => {
state.isLoading = false
state.ordersGroups = action.payload
},
/**
* Updates the modification date of an orders group.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {string} action.payload.id - The ID of the orders group to update.
*/
updateOrdersGroupDate: (state, action) => {
const { id } = action.payload
const orderGroup = state.ordersGroups.find((group) => group._id === id)
if (orderGroup) {
orderGroup.date_modification = new Date().toISOString()
}
},
/**
* Adds a count to the orders references in an orders group.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {string} action.payload.id - The ID of the orders group to update.
* @param {number} action.payload.addRefCount - The count to add.
*/
addOrdersToOrdersGroupCount: (state, action) => {
const { id, addRefCount } = action.payload
const orderGroup = state.ordersGroups.find((group) => group._id === id)
if (orderGroup) {
if (!orderGroup.orders_references_count) {
orderGroup.orders_references_count = 0
}
orderGroup.orders_references_count += addRefCount
}
},
/**
* Removes a count from the orders references in an orders group.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {string} action.payload.id - The ID of the orders group to update.
* @param {number} action.payload.removeRefCount - The count to remove.
*/
removeOrdersToOrdersGroupCount: (state, action) => {
const { id, removeRefCount } = action.payload
const orderGroup = state.ordersGroups.find((group) => group._id === id)
if (orderGroup) {
if (!orderGroup.orders_references_count) {
orderGroup.orders_references_count = 0
}
orderGroup.orders_references_count -= removeRefCount
}
},
/**
* Sets the default orders group status ID based on provided data.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {Object} action.payload.data - The data used to determine the default status.
*/
setDefaultOrdersGroupsStatusId: (state, action) => {
const { data } = action.payload
state.defaultOrdersGroupStatusId = findDefaultOrdersGroupsStatus(data)
},
/**
* Sets the modal match invoice is open state.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {boolean} action.payload - The state of the modal match invoice.
*/
setModalMatchInvoiceIsOpen: (state, action) => {
state.modalMatchInvoiceIsOpen = action.payload
},
/**
* Sets the matching orders selected id.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {string} action.payload - The id of the matching orders.
*/
setMatchingOrdersSelectedId: (state, action) => {
state.matchingOrdersSelectedId = action.payload
},
/**
* Sets the modal search ref is open state.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {boolean} action.payload - The state of the modal search ref.
*/
setModalSearchRefIsOpen: (state, action) => {
state.modalSearchRefIsOpen = action.payload
},
/**
* Sets the order seleted from edit ref.
* @param {OrdersState} state - The current state of the orders.
* @param {Object} action - Redux action containing the payload.
* @param {Object} action.payload - The order seleted from edit ref.
*/
setOrderSeletedFromEditRef: (state, action) => {
state.orderSeletedFromEditRef = action.payload
},
},
})
const { actions, reducer } = userSlice
export const {
ordersPending,
setOrdersGroupId,
ordersError,
ordersQuit,
setOrdersGroupsList,
addOrdersToOrdersGroupCount,
removeOrdersToOrdersGroupCount,
setDefaultOrdersGroupsStatusId,
updateOrdersGroupDate,
setModalMatchInvoiceIsOpen,
setMatchingOrdersSelectedId,
setModalSearchRefIsOpen,
setOrderSeletedFromEditRef,
resetOrders,
} = actions
export default reducer
/**
* Selector to get the current orders group ID.
* @param {Object} state - The global Redux state.
* @returns {string} - The current orders group ID.
*/
export const selectOrdersGroupId = (state) => state.orders.currentOrdersGroupId
/**
* Selector to get the list of orders groups.
* @param {Object} state - The global Redux state.
* @returns {Array} - The list of orders groups.
*/
export const selectOrdersGroupsList = (state) => state.orders.ordersGroups
/**
* Selector to get the modal match invoice is open state.
* @param {Object} state - The global Redux state.
* @returns {boolean} - The state of the modal match invoice.
*/
export const selectModalMatchInvoiceIsOpen = (state) =>
state.orders.modalMatchInvoiceIsOpen
/**
* Selector to get the matching orders selected id.
* @param {Object} state - The global Redux state.
* @returns {string} - The id of the matching orders.
*/
export const selectMatchingOrdersSelectedId = (state) =>
state.orders.matchingOrdersSelectedId
/**
* Selector to get the modal search ref is open state.
* @param {Object} state - The global Redux state.
* @returns {boolean} - The state of the modal search ref.
*/
export const selectModalSearchRefIsOpen = (state) =>
state.orders.modalSearchRefIsOpen
/**
* Selector to get the order seleted from edit ref.
* @param {Object} state - The global Redux state.
* @returns {Object} - The order seleted from edit ref.
*/
export const selectOrderSeletedFromEditRef = (state) =>
state.orders.orderSeletedFromEditRef
/**
* Selector to determine if orders are editable based on the current orders group status.
* @param {Object} state - The global Redux state.
* @returns {boolean} - True if orders are editable, false otherwise.
*/
export const selectOrdersAreEditable = (state) => {
const currentOrdersGroupId = state.orders.currentOrdersGroupId
const currentOrdersGroup = state.orders.ordersGroups.find(
(group) => group._id === currentOrdersGroupId
)
if (!currentOrdersGroup || !currentOrdersGroup.status) {
return false
}
const statusDescription =
currentOrdersGroup.status.orders_group_status_description
return statusDescription === 'A valider' || statusDescription === 'En cours'
}