@ritas-inc/prodplan-app
v1.0.44
Published
TypeScript client for Rita's Production Plan API
Maintainers
Readme
@ritas-inc/prodplan-app
TypeScript client for Rita's Production Plan API. This package provides a clean, type-safe interface for interacting with the Production Plan API, abstracting away HTTP complexity and providing comprehensive error handling.
Installation
npm install @ritas-inc/prodplan-appQuick Start
import { ProdPlanClient } from '@ritas-inc/prodplan-app'
const client = new ProdPlanClient({
apiUrl: 'https://api.ritas.com/prodplan/api/v1'
})
// Login
await client.login({
CompanyDB: 'RITA_TEST',
UserName: 'admin',
Password: 'password123'
})
// Create a production plan
const plan = await client.createPlan({
user: 'production_user',
products: [
{ itemCode: 'ITEM001', quantity: 100 },
{ itemCode: 'ITEM002', quantity: 50 }
]
})
console.log('Plan created:', plan)Configuration
Constructor Options
const client = new ProdPlanClient({
apiUrl: 'https://api.ritas.com/prodplan/api/v1', // Required
timeout: 30000, // Optional: Request timeout in ms (default: 30000)
retryAttempts: 3, // Optional: Number of retry attempts (default: 3)
xUserId: 'user-123' // Optional: Initialize with existing xUserId for pre-authenticated client
})Environment Variables
You can also configure the client using environment variables:
PRODPLAN_API_URL- API base URLPRODPLAN_TIMEOUT- Request timeout in millisecondsPRODPLAN_RETRY_ATTEMPTS- Number of retry attempts
// Uses environment variables for configuration
const client = new ProdPlanClient({
apiUrl: process.env.PRODPLAN_API_URL! // Required if not provided in constructor
})API Reference
Authentication
login(credentials: LoginCredentials): Promise<AuthResponse>
Authenticate with the Production Plan API using SAP B1 credentials.
const auth = await client.login({
CompanyDB: 'RITA_TEST',
UserName: 'admin',
Password: 'password123'
})
console.log('User ID:', auth.xUserId)logout(): void
Clear authentication state.
client.logout()isAuthenticated(): boolean
Check if the client is currently authenticated.
if (client.isAuthenticated()) {
console.log('Client is authenticated')
}setUserId(userId: string): void
Set the xUserId for authentication. Useful for creating multiple client instances with the same authentication.
client.setUserId('user-123')
console.log('Client is now authenticated:', client.isAuthenticated())getUserId(): string | null
Get the current xUserId. Returns null if not authenticated.
const userId = client.getUserId()
if (userId) {
console.log('Current user ID:', userId)
}Production Plans
createPlan(planData: CreatePlanRequest): Promise<Plan>
Create a new production plan.
const plan = await client.createPlan({
user: 'production_user',
products: [
{ itemCode: 'ITEM001', quantity: 100 },
{ itemCode: 'ITEM002', quantity: 50 },
{ itemCode: 'ITEM003', quantity: 25 }
]
})updatePlanProducts(planId: number, request: UpdatePlanProductsRequest): Promise<void>
Update the products in an existing production plan.
await client.updatePlanProducts(123, {
products: [
{ itemCode: 'ITEM001', quantity: 150 }, // Updated quantity
{ itemCode: 'ITEM004', quantity: 75 } // New product
]
})generateWorkOrders(planId: number, dateRange: DateRange): Promise<WorkOrderGenerationResponse>
Generate work orders for a production plan within a specified date range.
const result = await client.generateWorkOrders(123, {
from: '2025-08-01',
to: '2025-08-31'
})
console.log('Work orders generated:', result.workOrdersGenerated)releasePlan(planId: number): Promise<PlanReleaseResponse>
Release a production plan, moving it to the next status in the workflow.
const result = await client.releasePlan(123)
console.log('Plan status:', result.status)cancelPlan(planId: number): Promise<void>
Cancel a production plan and clean up associated work orders.
await client.cancelPlan(123)
console.log('Plan cancelled successfully')Session Management
checkSession(): Promise<SessionStatus>
Check if the current SAP B1 session is still valid. Useful for long-running applications or when you need to verify session status before performing operations.
const sessionStatus = await client.checkSession()
if (sessionStatus.valid) {
console.log('Session is active')
console.log('Session checked at:', sessionStatus.checkedAt)
} else {
console.log('Session is invalid - need to re-authenticate')
}isSessionValid(): Promise<boolean>
Simplified boolean check for session validity. Automatically handles authentication errors and returns false for invalid sessions, while re-throwing other types of errors (network issues, service problems).
const isValid = await client.isSessionValid()
if (!isValid) {
// Re-authenticate
await client.login(credentials)
}
// Proceed with operations
await client.createPlan(planData)Health Check
healthCheck(): Promise<HealthStatus>
Check the health status of the Production Plan API.
const health = await client.healthCheck()
console.log('API Status:', health.status)
console.log('Uptime:', health.uptime, 'seconds')
console.log('Memory Usage:', health.memory.used, 'MB')Error Handling
The client provides comprehensive error handling with specific error types for different scenarios:
import {
ProdPlanClient,
AuthenticationError,
ValidationError,
NotFoundError,
ServerError,
NetworkError,
TimeoutError
} from '@ritas-inc/prodplan-app'
try {
await client.createPlan(planData)
} catch (error) {
if (error instanceof AuthenticationError) {
console.log('Authentication failed, need to login again')
await client.login(credentials)
} else if (error instanceof ValidationError) {
console.log('Invalid plan data:', error.problem.issues)
} else if (error instanceof NotFoundError) {
console.log('Resource not found:', error.problem.detail)
} else if (error instanceof ServerError) {
console.log('Server error occurred:', error.problem.title)
} else if (error instanceof NetworkError) {
console.log('Network error:', error.message)
} else if (error instanceof TimeoutError) {
console.log('Request timed out:', error.message)
} else {
console.log('Unexpected error:', error.message)
}
}Error Properties
All API errors extend ProdPlanApiError and include detailed information:
try {
await client.createPlan(invalidData)
} catch (error) {
if (error instanceof ProdPlanApiError) {
console.log('Status:', error.status)
console.log('Type:', error.problem.type)
console.log('Title:', error.problem.title)
console.log('Detail:', error.problem.detail)
console.log('Issues:', error.problem.issues)
// Check error category
console.log('Is client error?', error.isClientError)
console.log('Is server error?', error.isServerError)
}
}TypeScript Support
The package is built with TypeScript and provides comprehensive type definitions:
import type {
LoginCredentials,
CreatePlanRequest,
PlanProduct,
DateRange,
Plan,
WorkOrderGenerationResponse,
HealthStatus,
SessionStatus,
ApiResponse
} from '@ritas-inc/prodplan-app'
// Type-safe plan creation
const planData: CreatePlanRequest = {
user: 'production_user',
products: [
{ itemCode: 'ITEM001', quantity: 100 }
]
}
// Type-safe date range
const dateRange: DateRange = {
from: '2025-08-01',
to: '2025-08-31'
}Advanced Usage
Sharing Authentication Between Client Instances
When working with multiple client instances in the same application, you can share the same authentication session to avoid multiple logins:
// Method 1: Using constructor with xUserId
const mainClient = new ProdPlanClient({
apiUrl: 'https://api.ritas.com/prodplan/api/v1'
})
await mainClient.login({
CompanyDB: 'RITA_PROD',
UserName: 'user',
Password: 'password'
})
// Create second client with the same xUserId
const secondClient = new ProdPlanClient({
apiUrl: 'https://api.ritas.com/prodplan/api/v1',
xUserId: mainClient.getUserId()! // Share the xUserId
})
console.log('Both clients authenticated:',
mainClient.isAuthenticated(),
secondClient.isAuthenticated()
) // Both return true// Method 2: Using setUserId method
const client1 = new ProdPlanClient({
apiUrl: 'https://api.ritas.com/prodplan/api/v1'
})
const client2 = new ProdPlanClient({
apiUrl: 'https://api.ritas.com/prodplan/api/v1'
})
// Login with first client
await client1.login(credentials)
// Share authentication with second client
client2.setUserId(client1.getUserId()!)
// Both clients can now make authenticated requests
await Promise.all([
client1.createPlan(plan1),
client2.createPlan(plan2)
])// Method 3: Managing authentication in a service class
class ProdPlanService {
private mainClient: ProdPlanClient
private workers: ProdPlanClient[] = []
constructor() {
this.mainClient = new ProdPlanClient({
apiUrl: process.env.PRODPLAN_API_URL!
})
}
async authenticate(credentials: LoginCredentials) {
await this.mainClient.login(credentials)
// Share authentication with all worker clients
this.workers.forEach(worker => {
worker.setUserId(this.mainClient.getUserId()!)
})
}
createWorkerClient(): ProdPlanClient {
const worker = new ProdPlanClient({
apiUrl: process.env.PRODPLAN_API_URL!,
xUserId: this.mainClient.getUserId() || undefined
})
this.workers.push(worker)
return worker
}
async processPlansInParallel(plans: CreatePlanRequest[]) {
// Create a worker client for each plan
const workers = plans.map(() => this.createWorkerClient())
// Process all plans in parallel
const results = await Promise.allSettled(
plans.map((plan, index) => workers[index].createPlan(plan))
)
return results
}
}Custom HTTP Configuration
const client = new ProdPlanClient({
apiUrl: 'https://api.ritas.com/prodplan/api/v1',
timeout: 60000, // 60 second timeout
retryAttempts: 5 // Retry failed requests 5 times
})Batch Operations
// Process multiple plans efficiently
const plans = [plan1, plan2, plan3]
const results = await Promise.allSettled(
plans.map(plan => client.createPlan(plan))
)
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Plan ${index + 1} created:`, result.value)
} else {
console.log(`Plan ${index + 1} failed:`, result.reason.message)
}
})Advanced Session Management
class ProductionPlanService {
private client: ProdPlanClient
constructor() {
this.client = new ProdPlanClient({
apiUrl: process.env.PRODPLAN_API_URL!
})
}
async ensureValidSession() {
// First check if client has local authentication
if (!this.client.isAuthenticated()) {
await this.login()
return
}
// Check if SAP B1 session is still valid
const isValid = await this.client.isSessionValid()
if (!isValid) {
console.log('Session expired, re-authenticating...')
await this.login()
}
}
private async login() {
await this.client.login({
CompanyDB: process.env.SAP_COMPANY_DB!,
UserName: process.env.SAP_USERNAME!,
Password: process.env.SAP_PASSWORD!
})
}
async createPlan(planData: CreatePlanRequest) {
await this.ensureValidSession()
return await this.client.createPlan(planData)
}
async performBatchOperations(plans: CreatePlanRequest[]) {
// Validate session once before batch operations
await this.ensureValidSession()
const results = []
for (const plan of plans) {
try {
const result = await this.client.createPlan(plan)
results.push({ success: true, data: result })
} catch (error) {
if (error instanceof AuthenticationError) {
// Session expired during batch, re-authenticate and retry once
await this.login()
try {
const result = await this.client.createPlan(plan)
results.push({ success: true, data: result })
} catch (retryError) {
results.push({ success: false, error: retryError })
}
} else {
results.push({ success: false, error })
}
}
}
return results
}
}Examples
Complete Production Planning Workflow
import { ProdPlanClient } from '@ritas-inc/prodplan-app'
async function completeWorkflow() {
const client = new ProdPlanClient({
apiUrl: process.env.PRODPLAN_API_URL!
})
try {
// 1. Login
await client.login({
CompanyDB: 'RITA_PROD',
UserName: 'planner',
Password: 'secure_password'
})
// 2. Check API health
const health = await client.healthCheck()
console.log('API is healthy:', health.status === 'healthy')
// 3. Create production plan
const plan = await client.createPlan({
user: 'production_planner',
products: [
{ itemCode: 'WIDGET_A', quantity: 500 },
{ itemCode: 'WIDGET_B', quantity: 300 }
]
})
console.log('Created plan:', plan.id)
// 4. Update plan if needed
await client.updatePlanProducts(plan.id, {
products: [
{ itemCode: 'WIDGET_A', quantity: 600 }, // Increased quantity
{ itemCode: 'WIDGET_B', quantity: 300 },
{ itemCode: 'WIDGET_C', quantity: 100 } // Added new product
]
})
// 5. Generate work orders
const workOrders = await client.generateWorkOrders(plan.id, {
from: '2025-08-01',
to: '2025-08-31'
})
console.log('Generated work orders:', workOrders.workOrdersGenerated)
// 6. Release the plan
const release = await client.releasePlan(plan.id)
console.log('Plan released with status:', release.status)
} catch (error) {
console.error('Workflow failed:', error)
// Clean up on error
if (error instanceof ValidationError) {
console.log('Fix these validation issues:', error.problem.issues)
}
}
}
completeWorkflow()Development
Building the Package
cd client
npm install
npm run buildPublishing
The package is automatically published to NPM when changes are pushed to the master branch. Version numbers are automatically incremented.
License
ISC
Support
For issues and support, please visit the GitHub repository.
