940 lines
30 KiB
Python
940 lines
30 KiB
Python
import frappe
|
|
from frappe import _
|
|
|
|
# Default fields for Work_Order doctype
|
|
WORK_ORDER_FIELDS = [
|
|
'name',
|
|
'owner',
|
|
'creation',
|
|
'modified',
|
|
'modified_by',
|
|
'docstatus',
|
|
'idx',
|
|
'workflow_state',
|
|
'company',
|
|
'naming_series',
|
|
'work_order_type',
|
|
'asset_type',
|
|
'manufacturer',
|
|
'serial_number',
|
|
'custom_priority_',
|
|
'asset',
|
|
'custom_maintenance_manager',
|
|
'department',
|
|
'repair_status',
|
|
'asset_name',
|
|
'supplier',
|
|
'custom_pending_reason',
|
|
'make',
|
|
'model',
|
|
'custom_site_contractor',
|
|
'custom_subcontractor',
|
|
'custom_service_agreement',
|
|
'custom_service_coverage',
|
|
'custom_start_date',
|
|
'custom_end_date',
|
|
'custom_total_amount',
|
|
'warranty',
|
|
'service_contract',
|
|
'covering_spare_parts',
|
|
'spare_parts_labour',
|
|
'covering_labour',
|
|
'ppm_only',
|
|
'failure_date',
|
|
'total_hours_spent',
|
|
'job_completed',
|
|
'custom_difference',
|
|
'custom_vendors_hrs',
|
|
'custom_deadline_date',
|
|
'custom_diffrence',
|
|
'feedback_rating',
|
|
'first_responded_on',
|
|
'assigned_manager',
|
|
'penalty',
|
|
'custom_assigned_supervisor',
|
|
'stock_consumption',
|
|
'need_procurement',
|
|
'repair_cost',
|
|
'total_repair_cost',
|
|
'capitalize_repair_cost',
|
|
'increase_in_asset_life',
|
|
'description',
|
|
'actions_performed',
|
|
'end_user',
|
|
'bio_med_dept'
|
|
]
|
|
|
|
# Child table: Asset Repair Consumed Item (stock_items)
|
|
STOCK_ITEMS_FIELDS = [
|
|
'name',
|
|
'owner',
|
|
'creation',
|
|
'modified',
|
|
'modified_by',
|
|
'docstatus',
|
|
'idx',
|
|
'parent',
|
|
'parentfield',
|
|
'parenttype',
|
|
'item_code',
|
|
'warehouse',
|
|
'valuation_rate',
|
|
'total_value',
|
|
'custom_available_stock'
|
|
]
|
|
|
|
# Child table: Invoice Table
|
|
INVOICE_TABLE_FIELDS = [
|
|
'name',
|
|
'owner',
|
|
'creation',
|
|
'modified',
|
|
'modified_by',
|
|
'docstatus',
|
|
'idx',
|
|
'parent',
|
|
'parentfield',
|
|
'parenttype',
|
|
'invoice_number',
|
|
'invoice_date',
|
|
'invoice_amount',
|
|
'vendor',
|
|
'description'
|
|
]
|
|
|
|
# Child table: CMQP Table
|
|
TABLE_CMQP_FIELDS = [
|
|
'name',
|
|
'owner',
|
|
'creation',
|
|
'modified',
|
|
'modified_by',
|
|
'docstatus',
|
|
'idx',
|
|
'parent',
|
|
'parentfield',
|
|
'parenttype',
|
|
'parameter',
|
|
'value',
|
|
'status',
|
|
'remarks'
|
|
]
|
|
|
|
|
|
def get_child_table_data(parent_name, parentfield, child_doctype, fields=None):
|
|
"""
|
|
Get child table data for a work order
|
|
|
|
Args:
|
|
parent_name: Name of the parent work order
|
|
parentfield: Field name of the child table in parent
|
|
child_doctype: Doctype of the child table
|
|
fields: List of fields to return
|
|
|
|
Returns:
|
|
List of child table records
|
|
"""
|
|
try:
|
|
return frappe.get_all(
|
|
child_doctype,
|
|
filters={
|
|
'parent': parent_name,
|
|
'parentfield': parentfield,
|
|
'parenttype': 'Work_Order'
|
|
},
|
|
fields=fields or ['*'],
|
|
order_by='idx asc'
|
|
)
|
|
except Exception:
|
|
return []
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_work_orders(filters=None, fields=None, limit=20, offset=0, order_by=None, include_child_tables=False):
|
|
"""
|
|
Get list of work orders with filters and pagination
|
|
|
|
Args:
|
|
filters: JSON string of filters (e.g., '{"company": "ABC Corp"}')
|
|
fields: JSON string of fields to return (e.g., '["work_order_type", "asset_name"]')
|
|
limit: Number of records to return (default: 20)
|
|
offset: Number of records to skip (default: 0)
|
|
order_by: Sort order (e.g., "creation desc")
|
|
include_child_tables: Whether to include child table data (default: False)
|
|
|
|
Returns:
|
|
{
|
|
"work_orders": [...],
|
|
"total_count": int,
|
|
"limit": int,
|
|
"offset": int,
|
|
"has_more": bool
|
|
}
|
|
"""
|
|
try:
|
|
import json
|
|
|
|
# Parse filters if provided
|
|
if filters and isinstance(filters, str):
|
|
filters = json.loads(filters)
|
|
|
|
# Parse fields if provided
|
|
if fields and isinstance(fields, str):
|
|
fields = json.loads(fields)
|
|
else:
|
|
fields = WORK_ORDER_FIELDS.copy()
|
|
|
|
# Parse include_child_tables
|
|
if isinstance(include_child_tables, str):
|
|
include_child_tables = include_child_tables.lower() in ('true', '1', 'yes')
|
|
|
|
# Get total count
|
|
total_count = frappe.db.count('Work_Order', filters=filters or {})
|
|
|
|
# Get work orders
|
|
work_orders = frappe.get_all(
|
|
'Work_Order',
|
|
filters=filters or {},
|
|
fields=fields,
|
|
limit_page_length=int(limit),
|
|
limit_start=int(offset),
|
|
order_by=order_by or 'creation desc'
|
|
)
|
|
|
|
# Include child tables if requested
|
|
if include_child_tables:
|
|
for work_order in work_orders:
|
|
work_order['stock_items'] = get_child_table_data(
|
|
work_order['name'],
|
|
'stock_items',
|
|
'Asset Repair Consumed Item',
|
|
STOCK_ITEMS_FIELDS
|
|
)
|
|
work_order['invoice_table'] = get_child_table_data(
|
|
work_order['name'],
|
|
'invoice_table',
|
|
'PI Table', # Adjust doctype name as needed
|
|
INVOICE_TABLE_FIELDS
|
|
)
|
|
work_order['table_cmqp'] = get_child_table_data(
|
|
work_order['name'],
|
|
'table_cmqp',
|
|
'Spare Parts', # Adjust doctype name as needed
|
|
TABLE_CMQP_FIELDS
|
|
)
|
|
|
|
# Calculate has_more
|
|
has_more = (int(offset) + int(limit)) < total_count
|
|
|
|
frappe.response['message'] = {
|
|
'work_orders': work_orders,
|
|
'total_count': total_count,
|
|
'limit': int(limit),
|
|
'offset': int(offset),
|
|
'has_more': has_more
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.log_error(frappe.get_traceback(), 'Get Work Orders API Error')
|
|
frappe.response['message'] = {
|
|
'error': str(e),
|
|
'work_orders': [],
|
|
'total_count': 0
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_work_order_details(work_order_name):
|
|
"""
|
|
Get detailed information about a specific work order
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
|
|
Returns:
|
|
Work Order document with all fields including child tables
|
|
"""
|
|
try:
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Check if user has permission to read this work order
|
|
if not frappe.has_permission('Work_Order', 'read', work_order_name):
|
|
frappe.throw(_('Not permitted to access this work order'))
|
|
|
|
# Get work order details
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
# Convert to dict and include child tables
|
|
work_order_dict = work_order.as_dict()
|
|
|
|
# Ensure child tables are included with all fields
|
|
work_order_dict['stock_items'] = [item.as_dict() for item in work_order.get('stock_items', [])]
|
|
work_order_dict['invoice_table'] = [item.as_dict() for item in work_order.get('invoice_table', [])]
|
|
work_order_dict['table_cmqp'] = [item.as_dict() for item in work_order.get('table_cmqp', [])]
|
|
|
|
frappe.response['message'] = work_order_dict
|
|
|
|
except Exception as e:
|
|
frappe.log_error(frappe.get_traceback(), 'Get Work Order Details API Error')
|
|
frappe.response['message'] = {
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def create_work_order(work_order_data):
|
|
"""
|
|
Create a new work order
|
|
|
|
Args:
|
|
work_order_data: JSON string containing work order fields including child tables
|
|
Example:
|
|
{
|
|
"company": "ABC Corp",
|
|
"work_order_type": "Repair (CM)",
|
|
"asset": "ASSET-001",
|
|
"stock_items": [
|
|
{"item_code": "ITEM-001", "warehouse": "Main Warehouse", "valuation_rate": 100}
|
|
],
|
|
"invoice_table": [...],
|
|
"table_cmqp": [...]
|
|
}
|
|
|
|
Returns:
|
|
Created work order document
|
|
"""
|
|
try:
|
|
import json
|
|
|
|
# Parse work order data
|
|
if isinstance(work_order_data, str):
|
|
work_order_data = json.loads(work_order_data)
|
|
|
|
# Check if user has permission to create work order
|
|
if not frappe.has_permission('Work_Order', 'create'):
|
|
frappe.throw(_('Not permitted to create work order'))
|
|
|
|
# Create new work order
|
|
work_order = frappe.get_doc({
|
|
'doctype': 'Work_Order',
|
|
**work_order_data
|
|
})
|
|
|
|
work_order.insert()
|
|
frappe.db.commit()
|
|
|
|
# Return created work order with child tables
|
|
work_order_dict = work_order.as_dict()
|
|
work_order_dict['stock_items'] = [item.as_dict() for item in work_order.get('stock_items', [])]
|
|
work_order_dict['invoice_table'] = [item.as_dict() for item in work_order.get('invoice_table', [])]
|
|
work_order_dict['table_cmqp'] = [item.as_dict() for item in work_order.get('table_cmqp', [])]
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'work_order': work_order_dict,
|
|
'message': _('Work Order created successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Create Work Order API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def update_work_order(work_order_name, work_order_data):
|
|
"""
|
|
Update an existing work order including child tables
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
work_order_data: JSON string containing fields to update
|
|
Example:
|
|
{
|
|
"repair_status": "In Progress",
|
|
"stock_items": [
|
|
{"item_code": "ITEM-001", "warehouse": "Main Warehouse", "valuation_rate": 100}
|
|
]
|
|
}
|
|
|
|
Returns:
|
|
Updated work order document
|
|
"""
|
|
try:
|
|
import json
|
|
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Parse work order data
|
|
if isinstance(work_order_data, str):
|
|
work_order_data = json.loads(work_order_data)
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
# Handle child tables separately
|
|
child_tables = ['stock_items', 'invoice_table', 'table_cmqp']
|
|
|
|
for key, value in work_order_data.items():
|
|
if key in child_tables:
|
|
# Clear existing child table entries and add new ones
|
|
work_order.set(key, [])
|
|
for item in value:
|
|
work_order.append(key, item)
|
|
elif hasattr(work_order, key):
|
|
setattr(work_order, key, value)
|
|
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
# Return updated work order with child tables
|
|
work_order_dict = work_order.as_dict()
|
|
work_order_dict['stock_items'] = [item.as_dict() for item in work_order.get('stock_items', [])]
|
|
work_order_dict['invoice_table'] = [item.as_dict() for item in work_order.get('invoice_table', [])]
|
|
work_order_dict['table_cmqp'] = [item.as_dict() for item in work_order.get('table_cmqp', [])]
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'work_order': work_order_dict,
|
|
'message': _('Work Order updated successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Update Work Order API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def delete_work_order(work_order_name):
|
|
"""
|
|
Delete a work order
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
|
|
Returns:
|
|
Success message
|
|
"""
|
|
try:
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Check if user has permission to delete this work order
|
|
if not frappe.has_permission('Work_Order', 'delete', work_order_name):
|
|
frappe.throw(_('Not permitted to delete this work order'))
|
|
|
|
# Delete work order (child tables will be deleted automatically)
|
|
frappe.delete_doc('Work_Order', work_order_name)
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'message': _('Work Order deleted successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Delete Work Order API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def update_work_order_status(work_order_name, repair_status=None, workflow_state=None):
|
|
"""
|
|
Update work order status
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
repair_status: New repair status (e.g., 'Open', 'In Progress', 'Completed')
|
|
workflow_state: New workflow state
|
|
|
|
Returns:
|
|
Updated work order document
|
|
"""
|
|
try:
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
# Update status fields
|
|
if repair_status:
|
|
work_order.repair_status = repair_status
|
|
|
|
if workflow_state:
|
|
work_order.workflow_state = workflow_state
|
|
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
# Return updated work order with child tables
|
|
work_order_dict = work_order.as_dict()
|
|
work_order_dict['stock_items'] = [item.as_dict() for item in work_order.get('stock_items', [])]
|
|
work_order_dict['invoice_table'] = [item.as_dict() for item in work_order.get('invoice_table', [])]
|
|
work_order_dict['table_cmqp'] = [item.as_dict() for item in work_order.get('table_cmqp', [])]
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'work_order': work_order_dict,
|
|
'message': _('Work Order status updated successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Update Work Order Status API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def add_stock_item(work_order_name, item_data):
|
|
"""
|
|
Add a stock item to work order's stock_items child table
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
item_data: JSON string containing stock item fields
|
|
Example:
|
|
{
|
|
"item_code": "ITEM-001",
|
|
"warehouse": "Main Warehouse",
|
|
"valuation_rate": 100,
|
|
"total_value": 500,
|
|
"custom_available_stock": 10
|
|
}
|
|
|
|
Returns:
|
|
Updated work order with stock items
|
|
"""
|
|
try:
|
|
import json
|
|
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Parse item data
|
|
if isinstance(item_data, str):
|
|
item_data = json.loads(item_data)
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order and add stock item
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
work_order.append('stock_items', item_data)
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'stock_items': [item.as_dict() for item in work_order.get('stock_items', [])],
|
|
'message': _('Stock item added successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Add Stock Item API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def remove_stock_item(work_order_name, item_name):
|
|
"""
|
|
Remove a stock item from work order's stock_items child table
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
item_name: Name/ID of the stock item to remove
|
|
|
|
Returns:
|
|
Updated work order with remaining stock items
|
|
"""
|
|
try:
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
if not item_name:
|
|
frappe.throw(_('Stock item name is required'))
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
# Find and remove the stock item
|
|
item_to_remove = None
|
|
for item in work_order.stock_items:
|
|
if item.name == item_name:
|
|
item_to_remove = item
|
|
break
|
|
|
|
if item_to_remove:
|
|
work_order.remove(item_to_remove)
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'stock_items': [item.as_dict() for item in work_order.get('stock_items', [])],
|
|
'message': _('Stock item removed successfully')
|
|
}
|
|
else:
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': _('Stock item not found')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Remove Stock Item API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def add_invoice(work_order_name, invoice_data):
|
|
"""
|
|
Add an invoice to work order's invoice_table child table
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
invoice_data: JSON string containing invoice fields
|
|
|
|
Returns:
|
|
Updated work order with invoices
|
|
"""
|
|
try:
|
|
import json
|
|
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Parse invoice data
|
|
if isinstance(invoice_data, str):
|
|
invoice_data = json.loads(invoice_data)
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order and add invoice
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
work_order.append('invoice_table', invoice_data)
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'invoice_table': [item.as_dict() for item in work_order.get('invoice_table', [])],
|
|
'message': _('Invoice added successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Add Invoice API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def remove_invoice(work_order_name, invoice_name):
|
|
"""
|
|
Remove an invoice from work order's invoice_table child table
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
invoice_name: Name/ID of the invoice to remove
|
|
|
|
Returns:
|
|
Updated work order with remaining invoices
|
|
"""
|
|
try:
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
if not invoice_name:
|
|
frappe.throw(_('Invoice name is required'))
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
# Find and remove the invoice
|
|
item_to_remove = None
|
|
for item in work_order.invoice_table:
|
|
if item.name == invoice_name:
|
|
item_to_remove = item
|
|
break
|
|
|
|
if item_to_remove:
|
|
work_order.remove(item_to_remove)
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'invoice_table': [item.as_dict() for item in work_order.get('invoice_table', [])],
|
|
'message': _('Invoice removed successfully')
|
|
}
|
|
else:
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': _('Invoice not found')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Remove Invoice API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def add_cmqp_item(work_order_name, cmqp_data):
|
|
"""
|
|
Add a CMQP item to work order's table_cmqp child table
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
cmqp_data: JSON string containing CMQP item fields
|
|
|
|
Returns:
|
|
Updated work order with CMQP items
|
|
"""
|
|
try:
|
|
import json
|
|
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Parse CMQP data
|
|
if isinstance(cmqp_data, str):
|
|
cmqp_data = json.loads(cmqp_data)
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order and add CMQP item
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
work_order.append('table_cmqp', cmqp_data)
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'table_cmqp': [item.as_dict() for item in work_order.get('table_cmqp', [])],
|
|
'message': _('CMQP item added successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Add CMQP Item API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def remove_cmqp_item(work_order_name, cmqp_name):
|
|
"""
|
|
Remove a CMQP item from work order's table_cmqp child table
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
cmqp_name: Name/ID of the CMQP item to remove
|
|
|
|
Returns:
|
|
Updated work order with remaining CMQP items
|
|
"""
|
|
try:
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
if not cmqp_name:
|
|
frappe.throw(_('CMQP item name is required'))
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
# Find and remove the CMQP item
|
|
item_to_remove = None
|
|
for item in work_order.table_cmqp:
|
|
if item.name == cmqp_name:
|
|
item_to_remove = item
|
|
break
|
|
|
|
if item_to_remove:
|
|
work_order.remove(item_to_remove)
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'table_cmqp': [item.as_dict() for item in work_order.get('table_cmqp', [])],
|
|
'message': _('CMQP item removed successfully')
|
|
}
|
|
else:
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': _('CMQP item not found')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Remove CMQP Item API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_work_order_child_tables(work_order_name, child_table=None):
|
|
"""
|
|
Get child table data for a work order
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
child_table: Specific child table to return ('stock_items', 'invoice_table', 'table_cmqp')
|
|
If None, returns all child tables
|
|
|
|
Returns:
|
|
Child table data
|
|
"""
|
|
try:
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Check if user has permission to read this work order
|
|
if not frappe.has_permission('Work_Order', 'read', work_order_name):
|
|
frappe.throw(_('Not permitted to access this work order'))
|
|
|
|
# Get work order
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
result = {}
|
|
|
|
if child_table:
|
|
if child_table == 'stock_items':
|
|
result['stock_items'] = [item.as_dict() for item in work_order.get('stock_items', [])]
|
|
elif child_table == 'invoice_table':
|
|
result['invoice_table'] = [item.as_dict() for item in work_order.get('invoice_table', [])]
|
|
elif child_table == 'table_cmqp':
|
|
result['table_cmqp'] = [item.as_dict() for item in work_order.get('table_cmqp', [])]
|
|
else:
|
|
frappe.throw(_('Invalid child table name'))
|
|
else:
|
|
result = {
|
|
'stock_items': [item.as_dict() for item in work_order.get('stock_items', [])],
|
|
'invoice_table': [item.as_dict() for item in work_order.get('invoice_table', [])],
|
|
'table_cmqp': [item.as_dict() for item in work_order.get('table_cmqp', [])]
|
|
}
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'work_order_name': work_order_name,
|
|
**result
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.log_error(frappe.get_traceback(), 'Get Work Order Child Tables API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def bulk_update_stock_items(work_order_name, stock_items):
|
|
"""
|
|
Bulk update/replace all stock items in a work order
|
|
|
|
Args:
|
|
work_order_name: Name/ID of the work order
|
|
stock_items: JSON string containing list of stock items
|
|
|
|
Returns:
|
|
Updated work order with new stock items
|
|
"""
|
|
try:
|
|
import json
|
|
|
|
if not work_order_name:
|
|
frappe.throw(_('Work Order name is required'))
|
|
|
|
# Parse stock items
|
|
if isinstance(stock_items, str):
|
|
stock_items = json.loads(stock_items)
|
|
|
|
# Check if user has permission to update this work order
|
|
if not frappe.has_permission('Work_Order', 'write', work_order_name):
|
|
frappe.throw(_('Not permitted to update this work order'))
|
|
|
|
# Get work order
|
|
work_order = frappe.get_doc('Work_Order', work_order_name)
|
|
|
|
# Clear existing stock items and add new ones
|
|
work_order.set('stock_items', [])
|
|
for item in stock_items:
|
|
work_order.append('stock_items', item)
|
|
|
|
work_order.save()
|
|
frappe.db.commit()
|
|
|
|
frappe.response['message'] = {
|
|
'success': True,
|
|
'stock_items': [item.as_dict() for item in work_order.get('stock_items', [])],
|
|
'message': _('Stock items updated successfully')
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.db.rollback()
|
|
frappe.log_error(frappe.get_traceback(), 'Bulk Update Stock Items API Error')
|
|
frappe.response['message'] = {
|
|
'success': False,
|
|
'error': str(e)
|
|
} |