fix: CoR server-side PDF, driver→Employee, customer list, address fix, button enable
This commit is contained in:
+130
-62
@@ -1,98 +1,166 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from reportlab.lib.pagesizes import letter
|
from reportlab.lib.pagesizes import letter
|
||||||
from reportlab.lib.units import inch
|
from reportlab.lib.units import inch
|
||||||
from reportlab.lib.colors import HexColor
|
from reportlab.lib.colors import HexColor, black, white, grey
|
||||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, Image
|
||||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||||
from reportlab.lib.enums import TA_CENTER
|
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
|
||||||
from reportlab.lib import colors
|
from reportlab.lib import colors
|
||||||
import sqlite3
|
|
||||||
import io
|
import io
|
||||||
|
import os
|
||||||
|
|
||||||
DB_PATH = '/opt/eim/eim.db'
|
|
||||||
DARK_BLUE = HexColor('#2F5496')
|
DARK_BLUE = HexColor('#2F5496')
|
||||||
LIGHT_BLUE = HexColor('#D6E4F0')
|
LIGHT_BLUE = HexColor('#D6E4F0')
|
||||||
GRAY = HexColor('#666666')
|
GRAY = HexColor('#666666')
|
||||||
|
|
||||||
def get_device_counts(pallet_number):
|
|
||||||
conn = sqlite3.connect(DB_PATH)
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
cur = conn.cursor()
|
|
||||||
cur.execute('SELECT device_type, COUNT(*) as count FROM devices WHERE pallet_number = ? GROUP BY device_type', (pallet_number,))
|
|
||||||
counts = {row['device_type']: row['count'] for row in cur.fetchall()}
|
|
||||||
conn.close()
|
|
||||||
return counts
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def generate_cor(pallet_number):
|
def generate_cor(company_name=None, weights=None, received_date=None, red_r2=None, contact_name=None, contact_number=None, address_line=None, pallet_name=None):
|
||||||
pallet = frappe.get_doc('Pallet', pallet_number)
|
"""Generate Certificate of Recycling PDF from form data."""
|
||||||
device_counts = get_device_counts(pallet_number)
|
|
||||||
|
# Format date
|
||||||
|
date_str = ''
|
||||||
|
if received_date:
|
||||||
|
from frappe.utils import formatdate
|
||||||
|
date_str = formatdate(received_date, 'MMMM d, Y')
|
||||||
|
|
||||||
|
items_recycled = 'e-waste'
|
||||||
|
if red_r2:
|
||||||
|
items_recycled += ' (' + red_r2 + ')'
|
||||||
|
|
||||||
output = io.BytesIO()
|
output = io.BytesIO()
|
||||||
doc = SimpleDocTemplate(output, pagesize=letter, topMargin=0.75*inch, bottomMargin=0.75*inch, leftMargin=0.75*inch, rightMargin=0.75*inch)
|
doc = SimpleDocTemplate(
|
||||||
|
output,
|
||||||
|
pagesize=letter,
|
||||||
|
topMargin=0.5 * inch,
|
||||||
|
bottomMargin=0.5 * inch,
|
||||||
|
leftMargin=0.75 * inch,
|
||||||
|
rightMargin=0.75 * inch
|
||||||
|
)
|
||||||
|
|
||||||
styles = getSampleStyleSheet()
|
styles = getSampleStyleSheet()
|
||||||
|
|
||||||
title_style = ParagraphStyle('CertTitle', parent=styles['Title'], fontSize=20, textColor=DARK_BLUE, spaceAfter=6, alignment=TA_CENTER)
|
# Custom styles matching the Electron app
|
||||||
body_style = ParagraphStyle('CertBody', parent=styles['Normal'], fontSize=11, spaceAfter=4)
|
date_style = ParagraphStyle('DateBlock', parent=styles['Normal'], fontSize=14, fontName='Times-Bold', alignment=TA_LEFT)
|
||||||
section_style = ParagraphStyle('SectionHeader', parent=styles['Heading2'], fontSize=14, textColor=DARK_BLUE, spaceBefore=12, spaceAfter=6)
|
title_style = ParagraphStyle('CertTitle', parent=styles['Title'], fontSize=16, fontName='Times-Bold', textColor=black, spaceAfter=6, alignment=TA_CENTER, letterSpacing=0.05)
|
||||||
|
cert_style = ParagraphStyle('CertBody', parent=styles['Normal'], fontName='Times-Roman', fontSize=12, spaceAfter=12, alignment=TA_JUSTIFY)
|
||||||
|
body_style = ParagraphStyle('BodyText2', parent=styles['Normal'], fontName='Times-Roman', fontSize=12, spaceAfter=10, alignment=TA_JUSTIFY)
|
||||||
|
bullet_style = ParagraphStyle('BulletText', parent=styles['Normal'], fontName='Times-Roman', fontSize=10, spaceAfter=4, leftIndent=24, bulletIndent=12, alignment=TA_JUSTIFY)
|
||||||
|
optin_style = ParagraphStyle('OptIn', parent=styles['Normal'], fontName='Times-Roman', fontSize=12, spaceAfter=10, alignment=TA_JUSTIFY)
|
||||||
|
sig_style = ParagraphStyle('Signature', parent=styles['Normal'], fontName='Times-Bold', fontSize=18, spaceBefore=18)
|
||||||
|
footer_style = ParagraphStyle('Footer', parent=styles['Normal'], fontName='Times-Roman', fontSize=10, textColor=GRAY)
|
||||||
|
|
||||||
elements = []
|
elements = []
|
||||||
elements.append(Paragraph('CERTIFICATE OF RECYCLING', title_style))
|
|
||||||
elements.append(Spacer(1, 6))
|
|
||||||
|
|
||||||
intro = 'Full Circle Electronics AZ, LLC (dba Westech Recyclers) certifies that the materials submitted for recycling are received and will be properly recycled in accordance with all state and federal recycling regulations and in accordance with the R2 Standard.'
|
# Header row: Date | Logo | Title
|
||||||
elements.append(Paragraph(intro, body_style))
|
logo_path = os.path.join(frappe.get_app_path('westech_r2'), 'public', 'images', 'cor_logo.png')
|
||||||
elements.append(Spacer(1, 8))
|
logo_img = None
|
||||||
elements.append(Paragraph('Materials Submitted by:', section_style))
|
if os.path.exists(logo_path):
|
||||||
|
logo_img = Image(logo_path, width=2.45 * inch, height=0.8 * inch)
|
||||||
|
|
||||||
pallet_data = [
|
header_data = [
|
||||||
['Company:', pallet.company_name or pallet.customer_number or 'N/A'],
|
[Paragraph(date_str, date_style), logo_img or Paragraph('', styles['Normal']), Paragraph('CERTIFICATE OF RECYCLING', title_style)]
|
||||||
['Pallet Number:', pallet.pallet_number or pallet_number],
|
|
||||||
['Date Received:', str(pallet.received_date or 'N/A')],
|
|
||||||
['Weight:', str(pallet.inbound_weight or 'N/A') + ' lbs'],
|
|
||||||
['Technician:', pallet.tester or 'N/A'],
|
|
||||||
]
|
]
|
||||||
|
header_table = Table(header_data, colWidths=[1.8 * inch, 2.45 * inch, 2.75 * inch])
|
||||||
|
header_table.setStyle(TableStyle([
|
||||||
|
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
|
||||||
|
('ALIGN', (0, 0), (0, 0), 'LEFT'),
|
||||||
|
('ALIGN', (1, 0), (1, 0), 'CENTER'),
|
||||||
|
('ALIGN', (2, 0), (2, 0), 'CENTER'),
|
||||||
|
]))
|
||||||
|
elements.append(header_table)
|
||||||
|
elements.append(Spacer(1, 18))
|
||||||
|
|
||||||
pallet_table = Table(pallet_data, colWidths=[1.5*inch, 4*inch])
|
# Certification paragraph
|
||||||
pallet_table.setStyle(TableStyle([
|
elements.append(Paragraph(
|
||||||
('BACKGROUND', (0, 0), (0, -1), LIGHT_BLUE),
|
'Full Circle Electronics AZ, LLC (dba Westech Recyclers) certifies that the '
|
||||||
('TEXTCOLOR', (0, 0), (0, -1), DARK_BLUE),
|
'materials submitted for recycling are received and will be properly recycled '
|
||||||
('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
|
'in accordance with all state and federal recycling regulations and in '
|
||||||
('FONTSIZE', (0, 0), (-1, -1), 10),
|
'accordance with the R2 Standard.',
|
||||||
|
cert_style
|
||||||
|
))
|
||||||
|
|
||||||
|
# Data table
|
||||||
|
data_rows = [
|
||||||
|
['Company:', company_name or 'N/A'],
|
||||||
|
['Weight:', weights or 'N/A'],
|
||||||
|
['Items Recycled:', items_recycled],
|
||||||
|
]
|
||||||
|
if contact_name:
|
||||||
|
data_rows.append(['Contact:', contact_name])
|
||||||
|
if contact_number:
|
||||||
|
data_rows.append(['Phone:', contact_number])
|
||||||
|
if address_line:
|
||||||
|
data_rows.append(['Address:', address_line])
|
||||||
|
|
||||||
|
data_table = Table(data_rows, colWidths=[3.36 * inch, 3.64 * inch])
|
||||||
|
data_table.setStyle(TableStyle([
|
||||||
|
('FONTNAME', (0, 0), (-1, -1), 'Times-Roman'),
|
||||||
|
('FONTSIZE', (0, 0), (-1, -1), 12),
|
||||||
('ALIGN', (0, 0), (0, -1), 'RIGHT'),
|
('ALIGN', (0, 0), (0, -1), 'RIGHT'),
|
||||||
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
|
('ALIGN', (1, 0), (1, -1), 'LEFT'),
|
||||||
|
('VALIGN', (0, 0), (-1, -1), 'TOP'),
|
||||||
|
('GRID', (0, 0), (-1, -1), 0.5, HexColor('#bfbfbf')),
|
||||||
('TOPPADDING', (0, 0), (-1, -1), 4),
|
('TOPPADDING', (0, 0), (-1, -1), 4),
|
||||||
('BOTTOMPADDING', (0, 0), (-1, -1), 4),
|
('BOTTOMPADDING', (0, 0), (-1, -1), 4),
|
||||||
|
('LEFTPADDING', (0, 0), (-1, -1), 6),
|
||||||
|
('RIGHTPADDING', (0, 0), (-1, -1), 6),
|
||||||
]))
|
]))
|
||||||
elements.append(pallet_table)
|
elements.append(data_table)
|
||||||
elements.append(Spacer(1, 12))
|
elements.append(Spacer(1, 12))
|
||||||
|
|
||||||
if device_counts:
|
# Body paragraphs
|
||||||
elements.append(Paragraph('Device Summary:', section_style))
|
elements.append(Paragraph(
|
||||||
device_data = [['Device Type', 'Count']]
|
'Full Circle Electronics AZ, LLC further acknowledges the acceptance and '
|
||||||
for dtype, count in sorted(device_counts.items()):
|
'recycling of any material potentially containing data. Data containing '
|
||||||
device_data.append([dtype or 'Unknown', str(count)])
|
'materials are stored in our secured facility ensuring the security of the '
|
||||||
device_table = Table(device_data, colWidths=[3*inch, 2*inch])
|
'unit(s) prior to data sanitization.',
|
||||||
device_table.setStyle(TableStyle([
|
body_style
|
||||||
('BACKGROUND', (0, 0), (-1, 0), DARK_BLUE),
|
))
|
||||||
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
|
|
||||||
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
|
elements.append(Paragraph(
|
||||||
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
|
'Data containing materials are sanitized in compliance with NIST 800-88 '
|
||||||
('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, HexColor('#F2F2F2')]),
|
'guidelines which is set forth by the U.S. government for a robust methodology '
|
||||||
]))
|
'for erasing data from storage media. Depending upon the media received, the '
|
||||||
elements.append(device_table)
|
'data destruction methods used are as follows:',
|
||||||
elements.append(Spacer(1, 12))
|
body_style
|
||||||
|
))
|
||||||
|
|
||||||
|
# Bullet list
|
||||||
|
bullets = [
|
||||||
|
'Hard disk and solid-state drives will either be logically sanitized using professional software or physically destroyed via shredding or degaussing.',
|
||||||
|
'Media cards and small storage devices will either be degaussed / shredded at our facility or sent straight to a smelter.',
|
||||||
|
'Data tapes or reels will either be degaussed or shredded at a vetted and approved downstream service provider.',
|
||||||
|
'Electronics with embedded storage chips will either be destroyed by physical destruction at our facility or at a vetted and approved downstream service provider.',
|
||||||
|
'Small electronics containing data will either be logically sanitized using the manufacturer\'s application for destroying data or sent to a vetted and approved downstream service provider.',
|
||||||
|
]
|
||||||
|
for b in bullets:
|
||||||
|
elements.append(Paragraph('\u2022 ' + b, bullet_style))
|
||||||
|
|
||||||
elements.append(HRFlowable(width='100%', thickness=1, color=DARK_BLUE, spaceBefore=12))
|
|
||||||
footer = Paragraph('Full Circle Electronics AZ, LLC | 220 S 9th St Phoenix, AZ 85034 | www.westechrecyclers.com | 602.256.7626',
|
|
||||||
ParagraphStyle('Footer', parent=styles['Normal'], fontSize=9, textColor=GRAY, alignment=TA_CENTER))
|
|
||||||
elements.append(Spacer(1, 6))
|
elements.append(Spacer(1, 6))
|
||||||
elements.append(footer)
|
|
||||||
|
# Opt-in
|
||||||
|
elements.append(Paragraph(
|
||||||
|
'Opt-in option. If you desire to be informed of our data destruction process '
|
||||||
|
'changes or be notified of any unlikely security breaches, please let us know.',
|
||||||
|
optin_style
|
||||||
|
))
|
||||||
|
|
||||||
|
# Signature
|
||||||
|
elements.append(Paragraph('Westech Recyclers', sig_style))
|
||||||
|
|
||||||
|
# Footer
|
||||||
|
elements.append(Spacer(1, 10))
|
||||||
|
elements.append(Paragraph(
|
||||||
|
'220 S 9th St Phoenix, AZ 85034 '
|
||||||
|
'<link href="http://www.westechrecyclers.com" color="#1155cc">www.westechrecyclers.com</link> '
|
||||||
|
'602.256.7626',
|
||||||
|
footer_style
|
||||||
|
))
|
||||||
|
|
||||||
doc.build(elements)
|
doc.build(elements)
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
|
||||||
frappe.response.filename = 'COR_' + pallet_number + '.pdf'
|
frappe.response.filename = 'COR_' + (company_name or 'document').replace(' ', '_') + '.pdf'
|
||||||
frappe.response.filecontent = output.getvalue()
|
frappe.response.filecontent = output.getvalue()
|
||||||
frappe.response.type = 'download'
|
frappe.response.type = 'download'
|
||||||
frappe.response.display_content_as = 'attachment'
|
frappe.response.display_content_as = 'attachment'
|
||||||
@@ -11,15 +11,15 @@ frappe.pages['intake'].on_page_load = function(wrapper) {
|
|||||||
}, 'add');
|
}, 'add');
|
||||||
|
|
||||||
page.add_inner_button('Refresh', function() {
|
page.add_inner_button('Refresh', function() {
|
||||||
load_recent_pallets();
|
load_customer_list();
|
||||||
});
|
});
|
||||||
|
|
||||||
$(wrapper).find('.layout-main-section').html(`
|
$(wrapper).find('.layout-main-section').html(`
|
||||||
<div class="intake-station" style="padding: 20px;">
|
<div class="intake-station" style="padding: 20px;">
|
||||||
<div id="intake-form-container" style="display:none;">
|
<div id="intake-form-container">
|
||||||
<div class="card" style="margin-bottom: 20px;">
|
<div class="card" style="margin-bottom: 20px;">
|
||||||
<div class="card-header" style="background: linear-gradient(135deg, #6f42c1, #28a745); color: white; padding: 15px;">
|
<div class="card-header" style="background: linear-gradient(135deg, #6f42c1, #28a745); color: white; padding: 15px;">
|
||||||
<h4 style="margin:0; color: white;">New Customer</h4>
|
<h4 style="margin:0; color: white;">Customer Management</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body" style="padding: 20px;">
|
<div class="card-body" style="padding: 20px;">
|
||||||
<form id="intake-form">
|
<form id="intake-form">
|
||||||
@@ -164,27 +164,25 @@ frappe.pages['intake'].on_page_load = function(wrapper) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="recent-pallets">
|
<div id="recent-pallets" style="display:none;">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header" style="background: #f8f9fa;">
|
<div class="card-header" style="background: #f8f9fa; display: flex; justify-content: space-between; align-items: center;">
|
||||||
<h5 style="margin:0;">Recent Pallets</h5>
|
<h5 style="margin:0;">Customers</h5>
|
||||||
|
<input type="text" id="customer-search" class="form-control" placeholder="Search..." style="width: 300px;">
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body" style="padding: 0;">
|
<div class="card-body" style="padding: 0;">
|
||||||
<table class="table table-striped table-hover" id="pallet-table">
|
<table class="table table-striped table-hover" id="customer-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Status</th>
|
<th>Company</th>
|
||||||
<th>Customer</th>
|
<th>Contact</th>
|
||||||
<th>Driver</th>
|
<th>Phone</th>
|
||||||
<th>Received</th>
|
<th>Address</th>
|
||||||
<th>RED/R2</th>
|
<th></th>
|
||||||
<th>Items</th>
|
|
||||||
<th>Weight</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="pallet-tbody">
|
<tbody id="customer-tbody">
|
||||||
<tr><td colspan="8" class="text-center">Loading...</td></tr>
|
<tr><td colspan="5" class="text-center">Loading...</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -206,7 +204,7 @@ frappe.pages['intake'].on_page_load = function(wrapper) {
|
|||||||
}
|
}
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
load_recent_pallets();
|
load_customer_list();
|
||||||
|
|
||||||
$('#received_date').on('change', function() {
|
$('#received_date').on('change', function() {
|
||||||
var d = new Date($(this).val() + 'T12:00:00');
|
var d = new Date($(this).val() + 'T12:00:00');
|
||||||
@@ -220,9 +218,7 @@ frappe.pages['intake'].on_page_load = function(wrapper) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$('#btn-cancel').on('click', function() {
|
$('#btn-cancel').on('click', function() {
|
||||||
$('#intake-form-container').hide();
|
show_customer_list();
|
||||||
$('#recent-pallets').show();
|
|
||||||
clear_form();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#btn-print-labels').on('click', function() {
|
$('#btn-print-labels').on('click', function() {
|
||||||
@@ -233,6 +229,14 @@ frappe.pages['intake'].on_page_load = function(wrapper) {
|
|||||||
generate_cor_report();
|
generate_cor_report();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#customer-search').on('input', function() {
|
||||||
|
var q = $(this).val().toLowerCase();
|
||||||
|
$('#customer-tbody tr').each(function() {
|
||||||
|
var text = $(this).text().toLowerCase();
|
||||||
|
$(this).toggle(text.indexOf(q) > -1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error('[INTAKE] FATAL:', e.message, e.stack);
|
console.error('[INTAKE] FATAL:', e.message, e.stack);
|
||||||
$(wrapper).find('.layout-main-section').html(
|
$(wrapper).find('.layout-main-section').html(
|
||||||
@@ -279,7 +283,7 @@ function setup_link_controls() {
|
|||||||
df: {
|
df: {
|
||||||
fieldtype: 'Link',
|
fieldtype: 'Link',
|
||||||
fieldname: 'driver',
|
fieldname: 'driver',
|
||||||
options: 'Customer',
|
options: 'Employee',
|
||||||
label: 'Driver',
|
label: 'Driver',
|
||||||
placeholder: 'Search driver...',
|
placeholder: 'Search driver...',
|
||||||
onchange: function() {}
|
onchange: function() {}
|
||||||
@@ -322,6 +326,9 @@ function fetch_customer_details(customer_name) {
|
|||||||
$('#contact_number').val(phone);
|
$('#contact_number').val(phone);
|
||||||
$('#contact_email').val(email);
|
$('#contact_email').val(email);
|
||||||
|
|
||||||
|
// Enable CoR button once we have a customer with data
|
||||||
|
$('#btn-generate-cor').prop('disabled', false);
|
||||||
|
|
||||||
// Get address — always fetch from Address record for full street+city+state+zip
|
// Get address — always fetch from Address record for full street+city+state+zip
|
||||||
if (c.customer_primary_address) {
|
if (c.customer_primary_address) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@@ -410,44 +417,43 @@ function show_intake_form() {
|
|||||||
$('#recent-pallets').hide();
|
$('#recent-pallets').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_recent_pallets() {
|
function show_customer_list() {
|
||||||
|
$('#intake-form-container').hide();
|
||||||
|
$('#recent-pallets').show();
|
||||||
|
clear_form();
|
||||||
|
load_customer_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_customer_list() {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'frappe.client.get_list',
|
method: 'frappe.client.get_list',
|
||||||
args: {
|
args: {
|
||||||
doctype: 'Pallet',
|
doctype: 'Customer',
|
||||||
fields: ['name', 'pallet_number', 'status', 'customer_number', 'company_name', 'driver', 'received_date', 'red_r2', 'total_items', 'weights', 'notes'],
|
fields: ['name', 'customer_name', 'customer_number', 'mobile_no', 'email_id', 'contact_persons', 'primary_address', 'customer_primary_address'],
|
||||||
limit_page_length: 20,
|
limit_page_length: 50,
|
||||||
order_by: 'creation desc'
|
order_by: 'customer_name asc'
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
var tbody = $('#pallet-tbody');
|
var tbody = $('#customer-tbody');
|
||||||
tbody.empty();
|
tbody.empty();
|
||||||
if (!r.message || r.message.length === 0) {
|
if (!r.message || r.message.length === 0) {
|
||||||
tbody.append('<tr><td colspan="8" class="text-center">No pallets yet. Click "New Customer" to create one.</td></tr>');
|
tbody.append('<tr><td colspan="5" class="text-center">No customers found.</td></tr>');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
r.message.forEach(function(p) {
|
r.message.forEach(function(c) {
|
||||||
var status_class = {
|
var contactName = '';
|
||||||
'Received': 'info',
|
if (c.contact_persons) {
|
||||||
'Sorting': 'warning',
|
var parts = c.contact_persons.split('|');
|
||||||
'Processing': 'primary',
|
if (parts.length > 0) contactName = parts[0].trim();
|
||||||
'Complete': 'success',
|
}
|
||||||
'Shipped': 'default'
|
|
||||||
}[p.status] || 'default';
|
|
||||||
|
|
||||||
tbody.append(
|
tbody.append(
|
||||||
'<tr>' +
|
'<tr style="cursor:pointer;" onclick="select_customer_from_list(\'' + c.name.replace(/'/g, "\\'") + '\')">' +
|
||||||
'<td><span class="label label-' + status_class + '">' + (p.status || 'Received') + '</span></td>' +
|
'<td><strong>' + (c.customer_name || c.name) + '</strong>' + (c.customer_number ? ' <span class="text-muted">(#' + c.customer_number + ')</span>' : '') + '</td>' +
|
||||||
'<td><strong>' + (p.customer_number || '') + '</strong></td>' +
|
'<td>' + contactName + '</td>' +
|
||||||
'<td>' + (p.driver || '') + '</td>' +
|
'<td>' + (c.mobile_no || '') + '</td>' +
|
||||||
'<td>' + (p.received_date || '') + '</td>' +
|
'<td>' + (c.primary_address ? c.primary_address.replace(/\n/g, ', ') : '') + '</td>' +
|
||||||
'<td>' + (p.red_r2 || '') + '</td>' +
|
'<td><button class="btn btn-xs btn-default"><i class="fa fa-arrow-right"></i></button></td>' +
|
||||||
'<td>' + (p.total_items || 0) + '</td>' +
|
|
||||||
'<td>' + (p.weights || '') + '</td>' +
|
|
||||||
'<td>' +
|
|
||||||
'<button class="btn btn-xs btn-default" onclick="edit_pallet(\'' + p.name + '\')"><i class="fa fa-edit"></i></button> ' +
|
|
||||||
'<button class="btn btn-xs btn-default" onclick="window.open(\'https://eim.diagalon.com/report/data-tracking?pallet=' + p.name + '\', \'_blank\')"><i class="fa fa-file-pdf-o"></i></button>' +
|
|
||||||
'</td>' +
|
|
||||||
'</tr>'
|
'</tr>'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -455,6 +461,11 @@ function load_recent_pallets() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function select_customer_from_list(customer_name) {
|
||||||
|
if (customer_number_control) customer_number_control.set_value(customer_name);
|
||||||
|
fetch_customer_details(customer_name);
|
||||||
|
}
|
||||||
|
|
||||||
function edit_pallet(name) {
|
function edit_pallet(name) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'frappe.client.get',
|
method: 'frappe.client.get',
|
||||||
@@ -550,12 +561,31 @@ function save_pallet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generate_cor_report() {
|
function generate_cor_report() {
|
||||||
var pallet_name = $('#intake-form-container').data('pallet-name');
|
var companyName = $('#company_name').val();
|
||||||
if (!pallet_name) {
|
if (!companyName) {
|
||||||
frappe.msgprint('Please save the intake first before generating CoR/AoR report.');
|
frappe.msgprint('Please select a customer first.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window.open('https://eim.diagalon.com/report/data-tracking?pallet=' + pallet_name, '_blank');
|
var args = {
|
||||||
|
company_name: companyName,
|
||||||
|
weights: $('#weights').val() || '',
|
||||||
|
received_date: $('#received_date').val() || '',
|
||||||
|
red_r2: $('#red_r2').val() || '',
|
||||||
|
contact_name: $('#contact_name').val() || '',
|
||||||
|
contact_number: $('#contact_number').val() || '',
|
||||||
|
address_line: $('#address_line').val() || '',
|
||||||
|
pallet_name: $('#intake-form-container').data('pallet-name') || ''
|
||||||
|
};
|
||||||
|
window.open('/api/method/westech_r2.api.cor_generator.generate_cor?'
|
||||||
|
+ '&company_name=' + encodeURIComponent(args.company_name)
|
||||||
|
+ '&weights=' + encodeURIComponent(args.weights)
|
||||||
|
+ '&received_date=' + encodeURIComponent(args.received_date)
|
||||||
|
+ '&red_r2=' + encodeURIComponent(args.red_r2)
|
||||||
|
+ '&contact_name=' + encodeURIComponent(args.contact_name)
|
||||||
|
+ '&contact_number=' + encodeURIComponent(args.contact_number)
|
||||||
|
+ '&address_line=' + encodeURIComponent(args.address_line)
|
||||||
|
+ '&pallet_name=' + encodeURIComponent(args.pallet_name)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.edit_pallet = edit_pallet;
|
window.edit_pallet = edit_pallet;
|
||||||
Reference in New Issue
Block a user