First template code generated from replit.com
This commit is contained in:
349
server/storage.ts
Normal file
349
server/storage.ts
Normal file
@@ -0,0 +1,349 @@
|
||||
import {
|
||||
type Product,
|
||||
type InsertProduct,
|
||||
type StockMovement,
|
||||
type InsertStockMovement,
|
||||
type Document,
|
||||
type InsertDocument,
|
||||
type Order,
|
||||
type InsertOrder,
|
||||
type Notification,
|
||||
type InsertNotification
|
||||
} from "@shared/schema";
|
||||
import { randomUUID } from "crypto";
|
||||
|
||||
export interface IStorage {
|
||||
// Products
|
||||
getProducts(): Promise<Product[]>;
|
||||
getProduct(id: string): Promise<Product | undefined>;
|
||||
getProductBySku(sku: string): Promise<Product | undefined>;
|
||||
createProduct(product: InsertProduct): Promise<Product>;
|
||||
updateProduct(id: string, product: Partial<InsertProduct>): Promise<Product | undefined>;
|
||||
deleteProduct(id: string): Promise<boolean>;
|
||||
searchProducts(query: string): Promise<Product[]>;
|
||||
getLowStockProducts(): Promise<Product[]>;
|
||||
getOutOfStockProducts(): Promise<Product[]>;
|
||||
|
||||
// Stock movements
|
||||
getStockMovements(productId?: string): Promise<StockMovement[]>;
|
||||
createStockMovement(movement: InsertStockMovement): Promise<StockMovement>;
|
||||
|
||||
// Documents
|
||||
getDocuments(): Promise<Document[]>;
|
||||
getDocument(id: string): Promise<Document | undefined>;
|
||||
createDocument(document: InsertDocument): Promise<Document>;
|
||||
updateDocument(id: string, document: Partial<InsertDocument>): Promise<Document | undefined>;
|
||||
deleteDocument(id: string): Promise<boolean>;
|
||||
|
||||
// Orders
|
||||
getOrders(): Promise<Order[]>;
|
||||
getOrder(id: string): Promise<Order | undefined>;
|
||||
createOrder(order: InsertOrder): Promise<Order>;
|
||||
updateOrder(id: string, order: Partial<InsertOrder>): Promise<Order | undefined>;
|
||||
|
||||
// Notifications
|
||||
getNotifications(): Promise<Notification[]>;
|
||||
createNotification(notification: InsertNotification): Promise<Notification>;
|
||||
markNotificationAsRead(id: string): Promise<boolean>;
|
||||
getUnreadNotificationCount(): Promise<number>;
|
||||
}
|
||||
|
||||
export class MemStorage implements IStorage {
|
||||
private products: Map<string, Product>;
|
||||
private stockMovements: Map<string, StockMovement>;
|
||||
private documents: Map<string, Document>;
|
||||
private orders: Map<string, Order>;
|
||||
private notifications: Map<string, Notification>;
|
||||
|
||||
constructor() {
|
||||
this.products = new Map();
|
||||
this.stockMovements = new Map();
|
||||
this.documents = new Map();
|
||||
this.orders = new Map();
|
||||
this.notifications = new Map();
|
||||
|
||||
// Initialize with sample data
|
||||
this.initializeSampleData();
|
||||
}
|
||||
|
||||
private initializeSampleData() {
|
||||
const sampleProducts: Product[] = [
|
||||
{
|
||||
id: "1",
|
||||
sku: "SH-001",
|
||||
name: "Safety Helmets - White",
|
||||
description: "High-quality safety helmets for construction work",
|
||||
currentStock: 125,
|
||||
minThreshold: 20,
|
||||
unit: "units",
|
||||
price: "29.99",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
sku: "WG-003",
|
||||
name: "Work Gloves - Medium",
|
||||
description: "Durable work gloves for general construction",
|
||||
currentStock: 8,
|
||||
minThreshold: 15,
|
||||
unit: "pairs",
|
||||
price: "12.50",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
sku: "HV-005",
|
||||
name: "Hi-Vis Vests - Large",
|
||||
description: "High-visibility safety vests",
|
||||
currentStock: 0,
|
||||
minThreshold: 10,
|
||||
unit: "units",
|
||||
price: "15.75",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
];
|
||||
|
||||
sampleProducts.forEach(product => {
|
||||
this.products.set(product.id, product);
|
||||
});
|
||||
|
||||
// Create notifications for low/out of stock items
|
||||
const lowStockNotification: Notification = {
|
||||
id: "notif-1",
|
||||
type: "low_stock",
|
||||
title: "Low Stock Alert",
|
||||
message: "Work Gloves - Medium is below minimum threshold",
|
||||
isRead: false,
|
||||
relatedId: "2",
|
||||
createdAt: new Date(),
|
||||
};
|
||||
|
||||
const outOfStockNotification: Notification = {
|
||||
id: "notif-2",
|
||||
type: "out_of_stock",
|
||||
title: "Out of Stock Alert",
|
||||
message: "Hi-Vis Vests - Large is out of stock",
|
||||
isRead: false,
|
||||
relatedId: "3",
|
||||
createdAt: new Date(),
|
||||
};
|
||||
|
||||
this.notifications.set("notif-1", lowStockNotification);
|
||||
this.notifications.set("notif-2", outOfStockNotification);
|
||||
}
|
||||
|
||||
// Products
|
||||
async getProducts(): Promise<Product[]> {
|
||||
return Array.from(this.products.values());
|
||||
}
|
||||
|
||||
async getProduct(id: string): Promise<Product | undefined> {
|
||||
return this.products.get(id);
|
||||
}
|
||||
|
||||
async getProductBySku(sku: string): Promise<Product | undefined> {
|
||||
return Array.from(this.products.values()).find(product => product.sku === sku);
|
||||
}
|
||||
|
||||
async createProduct(insertProduct: InsertProduct): Promise<Product> {
|
||||
const id = randomUUID();
|
||||
const product: Product = {
|
||||
...insertProduct,
|
||||
id,
|
||||
description: insertProduct.description ?? null,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.products.set(id, product);
|
||||
return product;
|
||||
}
|
||||
|
||||
async updateProduct(id: string, updates: Partial<InsertProduct>): Promise<Product | undefined> {
|
||||
const product = this.products.get(id);
|
||||
if (!product) return undefined;
|
||||
|
||||
const updatedProduct: Product = {
|
||||
...product,
|
||||
...updates,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.products.set(id, updatedProduct);
|
||||
return updatedProduct;
|
||||
}
|
||||
|
||||
async deleteProduct(id: string): Promise<boolean> {
|
||||
return this.products.delete(id);
|
||||
}
|
||||
|
||||
async searchProducts(query: string): Promise<Product[]> {
|
||||
const products = Array.from(this.products.values());
|
||||
const lowercaseQuery = query.toLowerCase();
|
||||
return products.filter(product =>
|
||||
product.name.toLowerCase().includes(lowercaseQuery) ||
|
||||
product.sku.toLowerCase().includes(lowercaseQuery) ||
|
||||
product.description?.toLowerCase().includes(lowercaseQuery)
|
||||
);
|
||||
}
|
||||
|
||||
async getLowStockProducts(): Promise<Product[]> {
|
||||
return Array.from(this.products.values()).filter(
|
||||
product => product.currentStock > 0 && product.currentStock <= product.minThreshold
|
||||
);
|
||||
}
|
||||
|
||||
async getOutOfStockProducts(): Promise<Product[]> {
|
||||
return Array.from(this.products.values()).filter(
|
||||
product => product.currentStock === 0
|
||||
);
|
||||
}
|
||||
|
||||
// Stock movements
|
||||
async getStockMovements(productId?: string): Promise<StockMovement[]> {
|
||||
const movements = Array.from(this.stockMovements.values());
|
||||
if (productId) {
|
||||
return movements.filter(movement => movement.productId === productId);
|
||||
}
|
||||
return movements;
|
||||
}
|
||||
|
||||
async createStockMovement(insertMovement: InsertStockMovement): Promise<StockMovement> {
|
||||
const id = randomUUID();
|
||||
const movement: StockMovement = {
|
||||
...insertMovement,
|
||||
id,
|
||||
reason: insertMovement.reason ?? null,
|
||||
createdAt: new Date(),
|
||||
};
|
||||
this.stockMovements.set(id, movement);
|
||||
|
||||
// Update product stock
|
||||
const product = this.products.get(insertMovement.productId);
|
||||
if (product) {
|
||||
let newStock = product.currentStock;
|
||||
if (insertMovement.type === 'in') {
|
||||
newStock += insertMovement.quantity;
|
||||
} else if (insertMovement.type === 'out') {
|
||||
newStock -= insertMovement.quantity;
|
||||
} else if (insertMovement.type === 'adjustment') {
|
||||
newStock = insertMovement.quantity;
|
||||
}
|
||||
|
||||
await this.updateProduct(insertMovement.productId, { currentStock: Math.max(0, newStock) });
|
||||
}
|
||||
|
||||
return movement;
|
||||
}
|
||||
|
||||
// Documents
|
||||
async getDocuments(): Promise<Document[]> {
|
||||
return Array.from(this.documents.values());
|
||||
}
|
||||
|
||||
async getDocument(id: string): Promise<Document | undefined> {
|
||||
return this.documents.get(id);
|
||||
}
|
||||
|
||||
async createDocument(insertDocument: InsertDocument): Promise<Document> {
|
||||
const id = randomUUID();
|
||||
const document: Document = {
|
||||
...insertDocument,
|
||||
id,
|
||||
content: insertDocument.content ?? {},
|
||||
status: insertDocument.status ?? "draft",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.documents.set(id, document);
|
||||
return document;
|
||||
}
|
||||
|
||||
async updateDocument(id: string, updates: Partial<InsertDocument>): Promise<Document | undefined> {
|
||||
const document = this.documents.get(id);
|
||||
if (!document) return undefined;
|
||||
|
||||
const updatedDocument: Document = {
|
||||
...document,
|
||||
...updates,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.documents.set(id, updatedDocument);
|
||||
return updatedDocument;
|
||||
}
|
||||
|
||||
async deleteDocument(id: string): Promise<boolean> {
|
||||
return this.documents.delete(id);
|
||||
}
|
||||
|
||||
// Orders
|
||||
async getOrders(): Promise<Order[]> {
|
||||
return Array.from(this.orders.values());
|
||||
}
|
||||
|
||||
async getOrder(id: string): Promise<Order | undefined> {
|
||||
return this.orders.get(id);
|
||||
}
|
||||
|
||||
async createOrder(insertOrder: InsertOrder): Promise<Order> {
|
||||
const id = randomUUID();
|
||||
const order: Order = {
|
||||
...insertOrder,
|
||||
id,
|
||||
status: insertOrder.status ?? "pending",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.orders.set(id, order);
|
||||
return order;
|
||||
}
|
||||
|
||||
async updateOrder(id: string, updates: Partial<InsertOrder>): Promise<Order | undefined> {
|
||||
const order = this.orders.get(id);
|
||||
if (!order) return undefined;
|
||||
|
||||
const updatedOrder: Order = {
|
||||
...order,
|
||||
...updates,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.orders.set(id, updatedOrder);
|
||||
return updatedOrder;
|
||||
}
|
||||
|
||||
// Notifications
|
||||
async getNotifications(): Promise<Notification[]> {
|
||||
return Array.from(this.notifications.values()).sort(
|
||||
(a, b) => (b.createdAt?.getTime() || 0) - (a.createdAt?.getTime() || 0)
|
||||
);
|
||||
}
|
||||
|
||||
async createNotification(insertNotification: InsertNotification): Promise<Notification> {
|
||||
const id = randomUUID();
|
||||
const notification: Notification = {
|
||||
...insertNotification,
|
||||
id,
|
||||
isRead: insertNotification.isRead ?? false,
|
||||
relatedId: insertNotification.relatedId ?? null,
|
||||
createdAt: new Date(),
|
||||
};
|
||||
this.notifications.set(id, notification);
|
||||
return notification;
|
||||
}
|
||||
|
||||
async markNotificationAsRead(id: string): Promise<boolean> {
|
||||
const notification = this.notifications.get(id);
|
||||
if (!notification) return false;
|
||||
|
||||
notification.isRead = true;
|
||||
this.notifications.set(id, notification);
|
||||
return true;
|
||||
}
|
||||
|
||||
async getUnreadNotificationCount(): Promise<number> {
|
||||
return Array.from(this.notifications.values()).filter(n => !n.isRead).length;
|
||||
}
|
||||
}
|
||||
|
||||
export const storage = new MemStorage();
|
||||
Reference in New Issue
Block a user