Initial commit: fixtures, hooks, doctype events, API, and JS
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
# Westech R2
|
||||||
|
|
||||||
|
R2 Tracking integration for Westech Recyclers ERPNext instance.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
frappe
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
with open("requirements.txt") as f:
|
||||||
|
install_requires = f.read().strip().split("\n")
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="westech_r2",
|
||||||
|
version="0.0.1",
|
||||||
|
description="R2 Tracking for Westech Recyclers",
|
||||||
|
author="Westech",
|
||||||
|
author_email="",
|
||||||
|
packages=find_packages(),
|
||||||
|
zip_safe=False,
|
||||||
|
include_package_data=True,
|
||||||
|
install_requires=install_requires,
|
||||||
|
)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
Metadata-Version: 2.4
|
||||||
|
Name: westech_r2
|
||||||
|
Version: 0.0.1
|
||||||
|
Summary: R2 Tracking for Westech Recyclers
|
||||||
|
Author: Westech
|
||||||
|
Author-email:
|
||||||
|
Requires-Dist: frappe
|
||||||
|
Dynamic: author
|
||||||
|
Dynamic: requires-dist
|
||||||
|
Dynamic: summary
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
README.md
|
||||||
|
setup.py
|
||||||
|
westech_r2/__init__.py
|
||||||
|
westech_r2/hooks.py
|
||||||
|
westech_r2.egg-info/PKG-INFO
|
||||||
|
westech_r2.egg-info/SOURCES.txt
|
||||||
|
westech_r2.egg-info/dependency_links.txt
|
||||||
|
westech_r2.egg-info/not-zip-safe
|
||||||
|
westech_r2.egg-info/requires.txt
|
||||||
|
westech_r2.egg-info/top_level.txt
|
||||||
|
westech_r2/config/__init__.py
|
||||||
|
westech_r2/config/desktop.py
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
frappe
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
westech_r2
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
__version__ = "0.0.1"
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def install_ssh():
|
||||||
|
"""Placeholder for SSH install functionality."""
|
||||||
|
return {"success": True, "message": "SSH install endpoint ready"}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import json
|
||||||
|
import re
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def optimize_routes(pickup_date=None):
|
||||||
|
"""Optimize routes for all trucks on a given date."""
|
||||||
|
if not pickup_date:
|
||||||
|
pickup_date = frappe.utils.today()
|
||||||
|
|
||||||
|
trucks = frappe.get_list("Truck Profile",
|
||||||
|
filters={"active": 1},
|
||||||
|
fields=["name", "truck_name", "total_slots", "weight_capacity"]
|
||||||
|
)
|
||||||
|
|
||||||
|
pickups = frappe.get_list("Scheduled Pickup",
|
||||||
|
filters={
|
||||||
|
"pickup_date": pickup_date,
|
||||||
|
"shipment_type": "Truck",
|
||||||
|
"truck_profile": ["is", "not set"]
|
||||||
|
},
|
||||||
|
fields=["name", "customer_number", "company_name", "estimated_items",
|
||||||
|
"estimated_weight", "gaylord_count", "gaylord_sizes", "slots_needed",
|
||||||
|
"latitude", "longitude"],
|
||||||
|
order_by="stop_order asc"
|
||||||
|
)
|
||||||
|
|
||||||
|
for pickup in pickups:
|
||||||
|
if not pickup.slots_needed and pickup.gaylord_sizes:
|
||||||
|
pickup.slots_needed = _calculate_slots(pickup.gaylord_sizes)
|
||||||
|
elif not pickup.slots_needed:
|
||||||
|
pickup.slots_needed = pickup.gaylord_count or 1
|
||||||
|
|
||||||
|
pickups.sort(key=lambda x: x.slots_needed or 0, reverse=True)
|
||||||
|
|
||||||
|
routes = {}
|
||||||
|
for truck in trucks:
|
||||||
|
routes[truck.name] = {
|
||||||
|
"truck": truck,
|
||||||
|
"pickups": [],
|
||||||
|
"used_slots": 0,
|
||||||
|
"used_weight": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
unassigned = []
|
||||||
|
|
||||||
|
for pickup in pickups:
|
||||||
|
assigned = False
|
||||||
|
for truck_name, route in routes.items():
|
||||||
|
truck = route["truck"]
|
||||||
|
slots = pickup.slots_needed or 0
|
||||||
|
weight = float(pickup.estimated_weight or 0)
|
||||||
|
|
||||||
|
if route["used_slots"] + slots <= truck.total_slots:
|
||||||
|
if truck.weight_capacity and route["used_weight"] + weight <= truck.weight_capacity:
|
||||||
|
route["pickups"].append(pickup)
|
||||||
|
route["used_slots"] += slots
|
||||||
|
route["used_weight"] += weight
|
||||||
|
assigned = True
|
||||||
|
frappe.db.set_value("Scheduled Pickup", pickup.name, "truck_profile", truck_name)
|
||||||
|
break
|
||||||
|
elif not truck.weight_capacity:
|
||||||
|
route["pickups"].append(pickup)
|
||||||
|
route["used_slots"] += slots
|
||||||
|
route["used_weight"] += weight
|
||||||
|
assigned = True
|
||||||
|
frappe.db.set_value("Scheduled Pickup", pickup.name, "truck_profile", truck_name)
|
||||||
|
break
|
||||||
|
if not assigned:
|
||||||
|
unassigned.append(pickup)
|
||||||
|
|
||||||
|
for truck_name, route in routes.items():
|
||||||
|
if route["pickups"]:
|
||||||
|
route["pickups"].sort(key=lambda p: (float(p.latitude or 0), float(p.longitude or 0)))
|
||||||
|
for i, pickup in enumerate(route["pickups"], 1):
|
||||||
|
frappe.db.set_value("Scheduled Pickup", pickup.name, "stop_order", i)
|
||||||
|
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"date": pickup_date,
|
||||||
|
"trucks_assigned": len([r for r in routes.values() if r["pickups"]]),
|
||||||
|
"total_pickups": len(pickups),
|
||||||
|
"unassigned": len(unassigned),
|
||||||
|
"routes": {
|
||||||
|
truck_name: {
|
||||||
|
"truck_name": route["truck"].truck_name,
|
||||||
|
"slots_used": route["used_slots"],
|
||||||
|
"slots_total": route["truck"].total_slots,
|
||||||
|
"weight_used": route["used_weight"],
|
||||||
|
"weight_capacity": route["truck"].weight_capacity,
|
||||||
|
"stops": len(route["pickups"]),
|
||||||
|
"pickups": [{"name": p.name, "company": p.company_name, "slots": p.slots_needed} for p in route["pickups"]]
|
||||||
|
}
|
||||||
|
for truck_name, route in routes.items() if route["pickups"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def _calculate_slots(gaylord_sizes_text):
|
||||||
|
if not gaylord_sizes_text:
|
||||||
|
return 0
|
||||||
|
size_map = {"small": 1, "medium": 2, "large": 3}
|
||||||
|
total = 0
|
||||||
|
matches = re.findall(r'(\d+)\s*(\w+)', gaylord_sizes_text.lower())
|
||||||
|
for count, size in matches:
|
||||||
|
slots = size_map.get(size, 1)
|
||||||
|
total += int(count) * slots
|
||||||
|
return total or 1
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return []
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def calculate_totals(doc, method):
|
||||||
|
"""Auto-calculate Load totals from child tables."""
|
||||||
|
total_devices = 0
|
||||||
|
total_weight = 0.0
|
||||||
|
|
||||||
|
for item in doc.get("material_items", []):
|
||||||
|
total_devices += item.total_count or 0
|
||||||
|
total_weight += item.weight or 0.0
|
||||||
|
|
||||||
|
doc.total_devices = total_devices
|
||||||
|
doc.total_weight = total_weight
|
||||||
|
|
||||||
|
total_hdd_wiped = 0
|
||||||
|
total_hdd_degaussed = 0
|
||||||
|
|
||||||
|
for hdd in doc.get("hdd_serials", []):
|
||||||
|
if hdd.wiped:
|
||||||
|
total_hdd_wiped += 1
|
||||||
|
if hdd.degaussed or hdd.shredded:
|
||||||
|
total_hdd_degaussed += 1
|
||||||
|
|
||||||
|
doc.total_hdd_wiped = total_hdd_wiped
|
||||||
|
doc.total_hdd_degaussed = total_hdd_degaussed
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def update_serial_nos(doc, method):
|
||||||
|
"""Update serial nos linked to this pallet."""
|
||||||
|
if doc.pallet_number:
|
||||||
|
serials = frappe.get_all("Serial No", filters={"pallet": doc.pallet_number}, fields=["name"])
|
||||||
|
doc.db_set("serial_count", len(serials))
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def set_title(doc, method):
|
||||||
|
"""Set title from company name and pickup date."""
|
||||||
|
if doc.company_name and doc.pickup_date:
|
||||||
|
doc.title = f"{doc.company_name} - {doc.pickup_date}"
|
||||||
|
elif doc.company_name:
|
||||||
|
doc.title = doc.company_name
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,308 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Westech",
|
||||||
|
"label": "Westech",
|
||||||
|
"title": "Westech",
|
||||||
|
"sequence_id": 0.0,
|
||||||
|
"for_user": null,
|
||||||
|
"parent_page": null,
|
||||||
|
"module": "Westech R2",
|
||||||
|
"icon": "stock",
|
||||||
|
"indicator_color": "green",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"hide_custom": 0,
|
||||||
|
"public": 1,
|
||||||
|
"is_hidden": 0,
|
||||||
|
"content": "[{\"type\": \"header\", \"data\": {\"text\": \"<span class=\\\"h4\\\"><b>Westech Recyclers</b></span>\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"New Intake\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Pallets\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Pallet List\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Scheduled Pickups\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Route Planner\"}}, {\"type\": \"spacer\", \"data\": {}}, {\"type\": \"header\", \"data\": {\"text\": \"<span class=\\\"h4\\\"><b>Tools</b></span>\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"EIM Device Portal\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"R2 Data Tracking\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Wes AI Assistant\"}}, {\"type\": \"spacer\", \"data\": {}}, {\"type\": \"header\", \"data\": {\"text\": \"<span class=\\\"h4\\\"><b>Records</b></span>\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Customers\"}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Suppliers\"}}]",
|
||||||
|
"doctype": "Workspace",
|
||||||
|
"number_cards": [],
|
||||||
|
"roles": [],
|
||||||
|
"charts": [],
|
||||||
|
"custom_blocks": [],
|
||||||
|
"shortcuts": [
|
||||||
|
{
|
||||||
|
"name": "udas5ds8ot",
|
||||||
|
"type": "Page",
|
||||||
|
"link_to": "intake",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "New Intake",
|
||||||
|
"icon": "add",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "udait4ne28",
|
||||||
|
"type": "Page",
|
||||||
|
"link_to": "eim-portal",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "EIM Device Portal",
|
||||||
|
"icon": "scan",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "uda22lpk4d",
|
||||||
|
"type": "Page",
|
||||||
|
"link_to": "r2-tracking",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "R2 Data Tracking",
|
||||||
|
"icon": "table",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "uda1ujmmbm",
|
||||||
|
"type": "DocType",
|
||||||
|
"link_to": "Pallet",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "Pallets",
|
||||||
|
"icon": "stock",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "udacp7r9mm",
|
||||||
|
"type": "DocType",
|
||||||
|
"link_to": "Customer",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "Customers",
|
||||||
|
"icon": "customer",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "udata7hnp2",
|
||||||
|
"type": "DocType",
|
||||||
|
"link_to": "Supplier",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "Suppliers",
|
||||||
|
"icon": "users",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "32sa54pcd0",
|
||||||
|
"type": "Page",
|
||||||
|
"link_to": "pallet-list",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "Pallet List",
|
||||||
|
"icon": "list",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dur8jjfd70",
|
||||||
|
"type": "Page",
|
||||||
|
"link_to": "route-planner",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "Route Planner",
|
||||||
|
"icon": "map",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "durrgfv1f7",
|
||||||
|
"type": "DocType",
|
||||||
|
"link_to": "Scheduled Pickup",
|
||||||
|
"url": null,
|
||||||
|
"doc_view": "List",
|
||||||
|
"kanban_board": null,
|
||||||
|
"label": "Scheduled Pickups",
|
||||||
|
"icon": "calendar",
|
||||||
|
"restrict_to_domain": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"stats_filter": null,
|
||||||
|
"color": null,
|
||||||
|
"format": null,
|
||||||
|
"doctype": "Workspace Shortcut"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_lists": [],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"name": "a3kfn55i4u",
|
||||||
|
"type": "Card Break",
|
||||||
|
"label": "Stock",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "DocType",
|
||||||
|
"link_to": "",
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"dependencies": "",
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a3khtlprab",
|
||||||
|
"type": "Link",
|
||||||
|
"label": "Warehouses",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "DocType",
|
||||||
|
"link_to": "Warehouse",
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"dependencies": "",
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a3kfh5qu2i",
|
||||||
|
"type": "Link",
|
||||||
|
"label": "Serial Nos",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "DocType",
|
||||||
|
"link_to": "Serial No",
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"dependencies": "",
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a3kd2bjk00",
|
||||||
|
"type": "Link",
|
||||||
|
"label": "Stock Entry",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "DocType",
|
||||||
|
"link_to": "Stock Entry",
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"dependencies": "",
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a3k18ofk9m",
|
||||||
|
"type": "Link",
|
||||||
|
"label": "Pallets",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "DocType",
|
||||||
|
"link_to": "Pallet",
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"dependencies": "",
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a3knidvhdq",
|
||||||
|
"type": "Link",
|
||||||
|
"label": "Stock Balance",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "Report",
|
||||||
|
"link_to": "Stock Balance",
|
||||||
|
"report_ref_doctype": "Stock Ledger Entry",
|
||||||
|
"dependencies": "",
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "q8h2lf3bto",
|
||||||
|
"type": "Card Break",
|
||||||
|
"label": "R2 Tracking",
|
||||||
|
"icon": "octicon octicon-shield-check",
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "DocType",
|
||||||
|
"link_to": null,
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"dependencies": null,
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "q8hvn93ud9",
|
||||||
|
"type": "Link",
|
||||||
|
"label": "Loads",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"hidden": 0,
|
||||||
|
"link_type": "DocType",
|
||||||
|
"link_to": "Load",
|
||||||
|
"report_ref_doctype": null,
|
||||||
|
"dependencies": null,
|
||||||
|
"only_for": null,
|
||||||
|
"onboard": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"link_count": 0,
|
||||||
|
"doctype": "Workspace Link"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
app_name = "westech_r2"
|
||||||
|
app_title = "Westech R2"
|
||||||
|
app_publisher = "Westech"
|
||||||
|
app_description = "R2 Tracking for Westech Recyclers"
|
||||||
|
app_email = ""
|
||||||
|
app_license = "MIT"
|
||||||
|
|
||||||
|
# Fixtures - these will be exported/imported
|
||||||
|
fixtures = [
|
||||||
|
"Custom Field",
|
||||||
|
"DocType",
|
||||||
|
"Workspace",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Required apps
|
||||||
|
required_apps = ["erpnext"]
|
||||||
|
|
||||||
|
# DocType event hooks
|
||||||
|
doc_events = {
|
||||||
|
"Pallet": {
|
||||||
|
"before_save": "westech_r2.doctype.pallet.pallet.update_serial_nos",
|
||||||
|
},
|
||||||
|
"Scheduled Pickup": {
|
||||||
|
"before_save": "westech_r2.doctype.scheduled_pickup.scheduled_pickup.set_title",
|
||||||
|
},
|
||||||
|
"Load": {
|
||||||
|
"before_save": "westech_r2.doctype.load.load.calculate_totals",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# Include JS in forms
|
||||||
|
app_include_js = [
|
||||||
|
"/assets/westech_r2/js/scheduled_pickup.js",
|
||||||
|
"/assets/westech_r2/js/load.js",
|
||||||
|
"/assets/westech_r2/js/pallet.js",
|
||||||
|
]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Westech R2
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
frappe.ui.form.on('Load', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
frm.add_custom_button(__('View Pallets'), function() {
|
||||||
|
frappe.set_route('List', 'Pallet', {'load': frm.doc.name});
|
||||||
|
}, __('Actions'));
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
frappe.ui.form.on('Pallet', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
frm.add_custom_button(__('View Serials'), function() {
|
||||||
|
frappe.set_route('List', 'Serial No', {
|
||||||
|
'pallet': frm.doc.pallet_number || frm.doc.name
|
||||||
|
});
|
||||||
|
}, __('View'));
|
||||||
|
|
||||||
|
frm.add_custom_button(__('Serials Spreadsheet'), function() {
|
||||||
|
frappe.set_route('query-report', 'Serial Nos by Pallet', {
|
||||||
|
'pallet': frm.doc.pallet_number || frm.doc.name
|
||||||
|
});
|
||||||
|
}, __('View'));
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
frappe.ui.form.on('Scheduled Pickup', {
|
||||||
|
customer_number: function(frm) {
|
||||||
|
var customer = frm.doc.customer_number;
|
||||||
|
if (!customer) {
|
||||||
|
clear_supplier_fields(frm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frappe.call({
|
||||||
|
method: 'frappe.client.get',
|
||||||
|
args: {doctype: 'Supplier', name: customer},
|
||||||
|
callback: function(r) {
|
||||||
|
if (!r.message) return;
|
||||||
|
var s = r.message;
|
||||||
|
if (!frm.doc.company_name && s.supplier_name) {
|
||||||
|
frm.set_value('company_name', s.supplier_name);
|
||||||
|
}
|
||||||
|
if (s.supplier_primary_contact) {
|
||||||
|
frappe.call({
|
||||||
|
method: 'frappe.client.get',
|
||||||
|
args: {doctype: 'Contact', name: s.supplier_primary_contact},
|
||||||
|
callback: function(cr) {
|
||||||
|
if (!cr.message) return;
|
||||||
|
var ct = cr.message;
|
||||||
|
var full_name = [ct.first_name, ct.last_name].filter(Boolean).join(' ');
|
||||||
|
if (!frm.doc.contact_name) frm.set_value('contact_name', full_name);
|
||||||
|
if (!frm.doc.contact_phone) frm.set_value('contact_phone', ct.phone || '');
|
||||||
|
if (!frm.doc.contact_email) frm.set_value('contact_email', ct.email_id || '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (s.supplier_primary_address) {
|
||||||
|
frappe.call({
|
||||||
|
method: 'frappe.client.get',
|
||||||
|
args: {doctype: 'Address', name: s.supplier_primary_address},
|
||||||
|
callback: function(ar) {
|
||||||
|
if (!ar.message) return;
|
||||||
|
var a = ar.message;
|
||||||
|
if (!frm.doc.address_line) frm.set_value('address_line', a.address_line1 || '');
|
||||||
|
if (!frm.doc.city) frm.set_value('city', a.city || '');
|
||||||
|
if (!frm.doc.state) frm.set_value('state', a.state || '');
|
||||||
|
if (!frm.doc.zip_code) frm.set_value('zip_code', a.pincode || '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (s.geocoded && s.latitude && s.longitude) {
|
||||||
|
frm.set_value('latitude', s.latitude);
|
||||||
|
frm.set_value('longitude', s.longitude);
|
||||||
|
frm.set_value('geocoded', 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function clear_supplier_fields(frm) {
|
||||||
|
frm.set_value('company_name', '');
|
||||||
|
frm.set_value('contact_name', '');
|
||||||
|
frm.set_value('contact_phone', '');
|
||||||
|
frm.set_value('contact_email', '');
|
||||||
|
frm.set_value('address_line', '');
|
||||||
|
frm.set_value('city', '');
|
||||||
|
frm.set_value('state', '');
|
||||||
|
frm.set_value('zip_code', '');
|
||||||
|
frm.set_value('latitude', '');
|
||||||
|
frm.set_value('longitude', '');
|
||||||
|
frm.set_value('geocoded', 0);
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user