This commit is contained in:
Flatlogic Bot 2025-06-14 23:08:26 +00:00
parent b645325c25
commit ed52d17b4b
24 changed files with 520 additions and 79 deletions

File diff suppressed because one or more lines are too long

View File

@ -350,7 +350,7 @@ module.exports = class OrdersDBApi {
},
},
{
tracking_number: {
destination: {
[Op.or]: searchTerms.map((term) => ({
[Op.iLike]: `%${term}%`,
})),

View File

@ -17,6 +17,8 @@ module.exports = class ShipmentsDBApi {
tracking_number: data.tracking_number || null,
shipment_date: data.shipment_date || null,
carrier: data.carrier || null,
destination: data.destination || null,
importHash: data.importHash || null,
createdById: currentUser.id,
updatedById: currentUser.id,
@ -49,6 +51,8 @@ module.exports = class ShipmentsDBApi {
tracking_number: item.tracking_number || null,
shipment_date: item.shipment_date || null,
carrier: item.carrier || null,
destination: item.destination || null,
importHash: item.importHash || null,
createdById: currentUser.id,
updatedById: currentUser.id,
@ -80,6 +84,11 @@ module.exports = class ShipmentsDBApi {
if (data.shipment_date !== undefined)
updatePayload.shipment_date = data.shipment_date;
if (data.carrier !== undefined) updatePayload.carrier = data.carrier;
if (data.destination !== undefined)
updatePayload.destination = data.destination;
updatePayload.updatedById = currentUser.id;
await shipments.update(updatePayload, { transaction });
@ -261,6 +270,20 @@ module.exports = class ShipmentsDBApi {
};
}
if (filter.carrier) {
where = {
...where,
[Op.and]: Utils.ilike('shipments', 'carrier', filter.carrier),
};
}
if (filter.destination) {
where = {
...where,
[Op.and]: Utils.ilike('shipments', 'destination', filter.destination),
};
}
if (filter.calendarStart && filter.calendarEnd) {
where = {
...where,
@ -408,22 +431,22 @@ module.exports = class ShipmentsDBApi {
where = {
[Op.or]: [
{ ['id']: Utils.uuid(query) },
Utils.ilike('shipments', 'tracking_number', query),
Utils.ilike('shipments', 'destination', query),
],
};
}
const records = await db.shipments.findAll({
attributes: ['id', 'tracking_number'],
attributes: ['id', 'destination'],
where,
limit: limit ? Number(limit) : undefined,
offset: offset ? Number(offset) : undefined,
orderBy: [['tracking_number', 'ASC']],
orderBy: [['destination', 'ASC']],
});
return records.map((record) => ({
id: record.id,
label: record.tracking_number,
label: record.destination,
}));
}
};

View File

@ -0,0 +1,49 @@
module.exports = {
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async up(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.addColumn(
'shipments',
'carrier',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction },
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async down(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn('shipments', 'carrier', {
transaction,
});
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
};

View File

@ -0,0 +1,49 @@
module.exports = {
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async up(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.addColumn(
'shipments',
'destination',
{
type: Sequelize.DataTypes.TEXT,
},
{ transaction },
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
/**
* @param {QueryInterface} queryInterface
* @param {Sequelize} Sequelize
* @returns {Promise<void>}
*/
async down(queryInterface, Sequelize) {
/**
* @type {Transaction}
*/
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn('shipments', 'destination', {
transaction,
});
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
};

View File

@ -22,6 +22,14 @@ module.exports = function (sequelize, DataTypes) {
type: DataTypes.DATE,
},
carrier: {
type: DataTypes.TEXT,
},
destination: {
type: DataTypes.TEXT,
},
importHash: {
type: DataTypes.STRING(255),
allowNull: true,

View File

@ -17,7 +17,7 @@ const OrdersData = [
total_amount: 150.75,
status: 'delivered',
status: 'pending',
// type code here for "relation_one" field
@ -33,7 +33,7 @@ const OrdersData = [
total_amount: 200,
status: 'packed',
status: 'returned',
// type code here for "relation_one" field
@ -49,7 +49,23 @@ const OrdersData = [
total_amount: 99.99,
status: 'returned',
status: 'delivered',
// type code here for "relation_one" field
// type code here for "relation_many" field
// type code here for "relation_one" field
},
{
order_number: 'ORD004',
order_date: new Date('2023-10-04T14:45:00Z'),
total_amount: 250.5,
status: 'pending',
// type code here for "relation_one" field
@ -85,7 +101,19 @@ const ReturnsData = [
},
{
return_id: 'Joseph J. Thomson',
return_id: 'Pierre Simon de Laplace',
return_date: new Date(Date.now()),
// type code here for "relation_one" field
// type code here for "relation_one" field
// type code here for "relation_one" field
},
{
return_id: 'Johannes Kepler',
return_date: new Date(Date.now()),
@ -108,6 +136,10 @@ const ShipmentsData = [
// type code here for "relation_one" field
// type code here for "relation_one" field
carrier: 'Jean Baptiste Lamarck',
destination: 'Alfred Binet',
},
{
@ -120,6 +152,10 @@ const ShipmentsData = [
// type code here for "relation_one" field
// type code here for "relation_one" field
carrier: 'George Gaylord Simpson',
destination: 'Albrecht von Haller',
},
{
@ -132,6 +168,26 @@ const ShipmentsData = [
// type code here for "relation_one" field
// type code here for "relation_one" field
carrier: 'Louis Pasteur',
destination: 'Marcello Malpighi',
},
{
tracking_number: 'Noam Chomsky',
shipment_date: new Date(Date.now()),
// type code here for "relation_one" field
// type code here for "relation_one" field
// type code here for "relation_one" field
carrier: 'George Gaylord Simpson',
destination: 'Gustav Kirchhoff',
},
];
@ -147,6 +203,10 @@ const OrganizationsData = [
{
name: 'Magento2 Store',
},
{
name: 'Lucretius',
},
];
// Similar logic for "relation_many"
@ -184,6 +244,17 @@ async function associateUserWithOrganization() {
if (User2?.setOrganization) {
await User2.setOrganization(relatedOrganization2);
}
const relatedOrganization3 = await Organizations.findOne({
offset: Math.floor(Math.random() * (await Organizations.count())),
});
const User3 = await Users.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (User3?.setOrganization) {
await User3.setOrganization(relatedOrganization3);
}
}
async function associateOrderWithOrganization() {
@ -219,6 +290,17 @@ async function associateOrderWithOrganization() {
if (Order2?.setOrganization) {
await Order2.setOrganization(relatedOrganization2);
}
const relatedOrganization3 = await Organizations.findOne({
offset: Math.floor(Math.random() * (await Organizations.count())),
});
const Order3 = await Orders.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Order3?.setOrganization) {
await Order3.setOrganization(relatedOrganization3);
}
}
// Similar logic for "relation_many"
@ -256,6 +338,17 @@ async function associateOrderWithOrganization() {
if (Order2?.setOrganization) {
await Order2.setOrganization(relatedOrganization2);
}
const relatedOrganization3 = await Organizations.findOne({
offset: Math.floor(Math.random() * (await Organizations.count())),
});
const Order3 = await Orders.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Order3?.setOrganization) {
await Order3.setOrganization(relatedOrganization3);
}
}
async function associateReturnWithOrder() {
@ -291,6 +384,17 @@ async function associateReturnWithOrder() {
if (Return2?.setOrder) {
await Return2.setOrder(relatedOrder2);
}
const relatedOrder3 = await Orders.findOne({
offset: Math.floor(Math.random() * (await Orders.count())),
});
const Return3 = await Returns.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Return3?.setOrder) {
await Return3.setOrder(relatedOrder3);
}
}
async function associateReturnWithOrganization() {
@ -326,6 +430,17 @@ async function associateReturnWithOrganization() {
if (Return2?.setOrganization) {
await Return2.setOrganization(relatedOrganization2);
}
const relatedOrganization3 = await Organizations.findOne({
offset: Math.floor(Math.random() * (await Organizations.count())),
});
const Return3 = await Returns.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Return3?.setOrganization) {
await Return3.setOrganization(relatedOrganization3);
}
}
async function associateReturnWithOrganization() {
@ -361,6 +476,17 @@ async function associateReturnWithOrganization() {
if (Return2?.setOrganization) {
await Return2.setOrganization(relatedOrganization2);
}
const relatedOrganization3 = await Organizations.findOne({
offset: Math.floor(Math.random() * (await Organizations.count())),
});
const Return3 = await Returns.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Return3?.setOrganization) {
await Return3.setOrganization(relatedOrganization3);
}
}
async function associateShipmentWithOrder() {
@ -396,6 +522,17 @@ async function associateShipmentWithOrder() {
if (Shipment2?.setOrder) {
await Shipment2.setOrder(relatedOrder2);
}
const relatedOrder3 = await Orders.findOne({
offset: Math.floor(Math.random() * (await Orders.count())),
});
const Shipment3 = await Shipments.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Shipment3?.setOrder) {
await Shipment3.setOrder(relatedOrder3);
}
}
async function associateShipmentWithOrganization() {
@ -431,6 +568,17 @@ async function associateShipmentWithOrganization() {
if (Shipment2?.setOrganization) {
await Shipment2.setOrganization(relatedOrganization2);
}
const relatedOrganization3 = await Organizations.findOne({
offset: Math.floor(Math.random() * (await Organizations.count())),
});
const Shipment3 = await Shipments.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Shipment3?.setOrganization) {
await Shipment3.setOrganization(relatedOrganization3);
}
}
async function associateShipmentWithOrganization() {
@ -466,6 +614,17 @@ async function associateShipmentWithOrganization() {
if (Shipment2?.setOrganization) {
await Shipment2.setOrganization(relatedOrganization2);
}
const relatedOrganization3 = await Organizations.findOne({
offset: Math.floor(Math.random() * (await Organizations.count())),
});
const Shipment3 = await Shipments.findOne({
order: [['id', 'ASC']],
offset: 3,
});
if (Shipment3?.setOrganization) {
await Shipment3.setOrganization(relatedOrganization3);
}
}
module.exports = {

View File

@ -25,6 +25,12 @@ router.use(checkCrudPermissions('shipments'));
* tracking_number:
* type: string
* default: tracking_number
* carrier:
* type: string
* default: carrier
* destination:
* type: string
* default: destination
*/
@ -310,7 +316,14 @@ router.get(
currentUser,
});
if (filetype && filetype === 'csv') {
const fields = ['id', 'tracking_number', 'shipment_date'];
const fields = [
'id',
'tracking_number',
'carrier',
'destination',
'shipment_date',
];
const opts = { fields };
try {
const csv = parse(payload.rows, opts);

View File

@ -47,7 +47,7 @@ module.exports = class SearchService {
returns: ['return_id'],
shipments: ['tracking_number'],
shipments: ['tracking_number', 'carrier', 'destination'],
organizations: ['name'],
};

View File

@ -0,0 +1 @@
{}

View File

@ -62,7 +62,7 @@ const CardShipments = ({
href={`/shipments/shipments-view/?id=${item.id}`}
className='text-lg font-bold leading-6 line-clamp-1'
>
{item.tracking_number}
{item.destination}
</Link>
<div className='ml-auto '>
@ -119,6 +119,28 @@ const CardShipments = ({
</div>
</dd>
</div>
<div className='flex justify-between gap-x-4 py-3'>
<dt className=' text-gray-500 dark:text-dark-600'>
Carrier
</dt>
<dd className='flex items-start gap-x-2'>
<div className='font-medium line-clamp-4'>
{item.carrier}
</div>
</dd>
</div>
<div className='flex justify-between gap-x-4 py-3'>
<dt className=' text-gray-500 dark:text-dark-600'>
Destination
</dt>
<dd className='flex items-start gap-x-2'>
<div className='font-medium line-clamp-4'>
{item.destination}
</div>
</dd>
</div>
</dl>
</li>
))}

View File

@ -80,6 +80,16 @@ const ListShipments = ({
)}
</p>
</div>
<div className={'flex-1 px-3'}>
<p className={'text-xs text-gray-500 '}>Carrier</p>
<p className={'line-clamp-2'}>{item.carrier}</p>
</div>
<div className={'flex-1 px-3'}>
<p className={'text-xs text-gray-500 '}>Destination</p>
<p className={'line-clamp-2'}>{item.destination}</p>
</div>
</Link>
<ListActionsPopover
onDelete={onDelete}

View File

@ -106,6 +106,30 @@ export const loadColumns = async (
params?.value?.id ?? params?.value,
},
{
field: 'carrier',
headerName: 'Carrier',
flex: 1,
minWidth: 120,
filterable: false,
headerClassName: 'datagrid--header',
cellClassName: 'datagrid--cell',
editable: hasUpdatePermission,
},
{
field: 'destination',
headerName: 'Destination',
flex: 1,
minWidth: 120,
filterable: false,
headerClassName: 'datagrid--header',
cellClassName: 'datagrid--cell',
editable: hasUpdatePermission,
},
{
field: 'actions',
type: 'actions',

View File

@ -60,21 +60,21 @@ export default {
shipmentsManyListFormatter(val) {
if (!val || !val.length) return [];
return val.map((item) => item.tracking_number);
return val.map((item) => item.destination);
},
shipmentsOneListFormatter(val) {
if (!val) return '';
return val.tracking_number;
return val.destination;
},
shipmentsManyListFormatterEdit(val) {
if (!val || !val.length) return [];
return val.map((item) => {
return { id: item.id, label: item.tracking_number };
return { id: item.id, label: item.destination };
});
},
shipmentsOneListFormatterEdit(val) {
if (!val) return '';
return { label: val.tracking_number, id: val.id };
return { label: val.destination, id: val.id };
},
rolesManyListFormatter(val) {

View File

@ -170,7 +170,7 @@ const EditOrders = () => {
component={SelectFieldMany}
options={initialValues.shipments}
itemRef={'shipments'}
showField={'tracking_number'}
showField={'destination'}
></Field>
</FormField>

View File

@ -168,7 +168,7 @@ const EditOrdersPage = () => {
component={SelectFieldMany}
options={initialValues.shipments}
itemRef={'shipments'}
showField={'tracking_number'}
showField={'destination'}
></Field>
</FormField>

View File

@ -113,6 +113,10 @@ const OrdersView = () => {
<th>TrackingNumber</th>
<th>ShipmentDate</th>
<th>Carrier</th>
<th>Destination</th>
</tr>
</thead>
<tbody>
@ -136,6 +140,10 @@ const OrdersView = () => {
item.shipment_date,
)}
</td>
<td data-label='carrier'>{item.carrier}</td>
<td data-label='destination'>{item.destination}</td>
</tr>
))}
</tbody>
@ -207,6 +215,10 @@ const OrdersView = () => {
<th>TrackingNumber</th>
<th>ShipmentDate</th>
<th>Carrier</th>
<th>Destination</th>
</tr>
</thead>
<tbody>
@ -230,6 +242,10 @@ const OrdersView = () => {
item.shipment_date,
)}
</td>
<td data-label='carrier'>{item.carrier}</td>
<td data-label='destination'>{item.destination}</td>
</tr>
))}
</tbody>

View File

@ -309,6 +309,10 @@ const OrganizationsView = () => {
<th>TrackingNumber</th>
<th>ShipmentDate</th>
<th>Carrier</th>
<th>Destination</th>
</tr>
</thead>
<tbody>
@ -332,6 +336,10 @@ const OrganizationsView = () => {
item.shipment_date,
)}
</td>
<td data-label='carrier'>{item.carrier}</td>
<td data-label='destination'>{item.destination}</td>
</tr>
))}
</tbody>
@ -356,6 +364,10 @@ const OrganizationsView = () => {
<th>TrackingNumber</th>
<th>ShipmentDate</th>
<th>Carrier</th>
<th>Destination</th>
</tr>
</thead>
<tbody>
@ -379,6 +391,10 @@ const OrganizationsView = () => {
item.shipment_date,
)}
</td>
<td data-label='carrier'>{item.carrier}</td>
<td data-label='destination'>{item.destination}</td>
</tr>
))}
</tbody>

View File

@ -47,6 +47,10 @@ const EditShipments = () => {
organization: null,
organizations: null,
carrier: '',
destination: '',
};
const [initialValues, setInitialValues] = useState(initVals);
@ -161,6 +165,14 @@ const EditShipments = () => {
></Field>
</FormField>
<FormField label='Carrier'>
<Field name='carrier' placeholder='Carrier' />
</FormField>
<FormField label='Destination'>
<Field name='destination' placeholder='Destination' />
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type='submit' color='info' label='Submit' />

View File

@ -47,6 +47,10 @@ const EditShipmentsPage = () => {
organization: null,
organizations: null,
carrier: '',
destination: '',
};
const [initialValues, setInitialValues] = useState(initVals);
@ -159,6 +163,14 @@ const EditShipmentsPage = () => {
></Field>
</FormField>
<FormField label='Carrier'>
<Field name='carrier' placeholder='Carrier' />
</FormField>
<FormField label='Destination'>
<Field name='destination' placeholder='Destination' />
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type='submit' color='info' label='Submit' />

View File

@ -30,6 +30,8 @@ const ShipmentsTablesPage = () => {
const [filters] = useState([
{ label: 'TrackingNumber', title: 'tracking_number' },
{ label: 'Carrier', title: 'carrier' },
{ label: 'Destination', title: 'destination' },
{ label: 'ShipmentDate', title: 'shipment_date', date: 'true' },

View File

@ -42,6 +42,10 @@ const initialValues = {
organization: '',
organizations: '',
carrier: '',
destination: '',
};
const ShipmentsNew = () => {
@ -113,6 +117,14 @@ const ShipmentsNew = () => {
></Field>
</FormField>
<FormField label='Carrier'>
<Field name='carrier' placeholder='Carrier' />
</FormField>
<FormField label='Destination'>
<Field name='destination' placeholder='Destination' />
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type='submit' color='info' label='Submit' />

View File

@ -30,6 +30,8 @@ const ShipmentsTablesPage = () => {
const [filters] = useState([
{ label: 'TrackingNumber', title: 'tracking_number' },
{ label: 'Carrier', title: 'carrier' },
{ label: 'Destination', title: 'destination' },
{ label: 'ShipmentDate', title: 'shipment_date', date: 'true' },

View File

@ -104,6 +104,16 @@ const ShipmentsView = () => {
<p>{shipments?.organizations?.name ?? 'No data'}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Carrier</p>
<p>{shipments?.carrier}</p>
</div>
<div className={'mb-4'}>
<p className={'block font-bold mb-2'}>Destination</p>
<p>{shipments?.destination}</p>
</div>
<BaseDivider />
<BaseButton