├── license.txt
├── requirements.txt
├── servicems
├── patches.txt
├── config
│ ├── __init__.py
│ ├── desktop.py
│ └── docs.py
├── servicems
│ └── __init__.py
├── templates
│ ├── __init__.py
│ └── pages
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ └── __init__.py
├── service_management
│ ├── __init__.py
│ ├── doctype
│ │ ├── __init__.py
│ │ ├── complains
│ │ │ ├── __init__.py
│ │ │ ├── complains.py
│ │ │ └── complains.json
│ │ ├── faults
│ │ │ ├── __init__.py
│ │ │ ├── faults.py
│ │ │ └── faults.json
│ │ ├── sold_by
│ │ │ ├── __init__.py
│ │ │ ├── test_sold_by.py
│ │ │ ├── sold_by.js
│ │ │ ├── sold_by.py
│ │ │ └── sold_by.json
│ │ ├── spare
│ │ │ ├── __init__.py
│ │ │ ├── test_spare.py
│ │ │ ├── spare.js
│ │ │ ├── spare.py
│ │ │ └── spare.json
│ │ ├── job_card_tasks
│ │ │ ├── __init__.py
│ │ │ ├── job_card_tasks.py
│ │ │ └── job_card_tasks.json
│ │ ├── service_task
│ │ │ ├── __init__.py
│ │ │ ├── test_service_task.py
│ │ │ ├── service_task.js
│ │ │ ├── service_task.py
│ │ │ └── service_task.json
│ │ ├── supplied_parts
│ │ │ ├── __init__.py
│ │ │ ├── supplied_parts.py
│ │ │ └── supplied_parts.json
│ │ ├── template_task
│ │ │ ├── __init__.py
│ │ │ ├── template_task.py
│ │ │ └── template_task.json
│ │ ├── vehicle_make
│ │ │ ├── __init__.py
│ │ │ ├── test_vehicle_make.py
│ │ │ ├── vehicle_make.js
│ │ │ ├── vehicle_make.py
│ │ │ └── vehicle_make.json
│ │ ├── vehicle_model
│ │ │ ├── __init__.py
│ │ │ ├── templates
│ │ │ │ ├── vehicle_model_row.html
│ │ │ │ └── vehicle_model.html
│ │ │ ├── test_vehicle_model.py
│ │ │ ├── vehicle_model.js
│ │ │ ├── vehicle_model.py
│ │ │ └── vehicle_model.json
│ │ ├── job_card_status
│ │ │ ├── __init__.py
│ │ │ ├── test_job_card_status.py
│ │ │ ├── job_card_status.js
│ │ │ ├── job_card_status.py
│ │ │ └── job_card_status.json
│ │ ├── job_card_template
│ │ │ ├── __init__.py
│ │ │ ├── job_card_template.py
│ │ │ └── job_card_template.json
│ │ ├── pre_inspection_item
│ │ │ ├── __init__.py
│ │ │ ├── pre_inspection_item.py
│ │ │ └── pre_inspection_item.json
│ │ ├── service_job_card
│ │ │ ├── __init__.py
│ │ │ ├── templates
│ │ │ │ ├── service_job_card_row.html
│ │ │ │ └── service_job_card.html
│ │ │ ├── test_service_job_card.py
│ │ │ ├── service_job_card_dashboard.py
│ │ │ ├── service_job_card.js
│ │ │ ├── service_job_card.py
│ │ │ └── service_job_card.json
│ │ ├── service_parts_entry
│ │ │ ├── __init__.py
│ │ │ ├── test_service_parts_entry.py
│ │ │ ├── service_parts_entry.js
│ │ │ ├── service_parts_entry.py
│ │ │ └── service_parts_entry.json
│ │ ├── service_settings
│ │ │ ├── __init__.py
│ │ │ ├── test_service_settings.py
│ │ │ ├── service_settings.js
│ │ │ ├── service_settings.py
│ │ │ └── service_settings.json
│ │ ├── service_template
│ │ │ ├── __init__.py
│ │ │ ├── test_service_template.py
│ │ │ ├── service_template.py
│ │ │ ├── service_template.js
│ │ │ └── service_template.json
│ │ ├── service_vehicle
│ │ │ ├── __init__.py
│ │ │ ├── test_service_vehicle.py
│ │ │ ├── service_vehicle.js
│ │ │ ├── service_vehicle.py
│ │ │ └── service_vehicle.json
│ │ ├── service_workshop
│ │ │ ├── __init__.py
│ │ │ ├── test_service_workshop.py
│ │ │ ├── service_workshop.js
│ │ │ ├── service_workshop.py
│ │ │ └── service_workshop.json
│ │ ├── job_card_items_supplied
│ │ │ ├── __init__.py
│ │ │ ├── job_card_items_supplied.py
│ │ │ └── job_card_items_supplied.json
│ │ ├── parts_and_consumable
│ │ │ ├── __init__.py
│ │ │ ├── test_parts_and_consumable.py
│ │ │ ├── parts_and_consumable.js
│ │ │ ├── parts_and_consumable.py
│ │ │ └── parts_and_consumable.json
│ │ ├── service_brake_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_brake_checklist.py
│ │ │ └── service_brake_checklist.json
│ │ ├── service_engine_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_engine_checklist.py
│ │ │ └── service_engine_checklist.json
│ │ ├── service_tyre_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_tyre_checklist.py
│ │ │ └── service_tyre_checklist.json
│ │ ├── service_vehicle_type
│ │ │ ├── __init__.py
│ │ │ ├── test_service_vehicle_type.py
│ │ │ ├── service_vehicle_type.js
│ │ │ ├── service_vehicle_type.py
│ │ │ └── service_vehicle_type.json
│ │ ├── service_air_system_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_air_system_checklist.py
│ │ │ └── service_air_system_checklist.json
│ │ ├── service_electrical_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_electrical_checklist.py
│ │ │ └── service_electrical_checklist.json
│ │ ├── service_electronics_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_electronics_checklist.py
│ │ │ └── service_electronics_checklist.json
│ │ ├── service_fuel_system_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_fuel_system_checklist.py
│ │ │ └── service_fuel_system_checklist.json
│ │ ├── service_lighting_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_lighting_checklist.py
│ │ │ └── service_lighting_checklist.json
│ │ ├── service_parts_entry_detail
│ │ │ ├── __init__.py
│ │ │ ├── service_parts_entry_detail.py
│ │ │ └── service_parts_entry_detail.json
│ │ ├── service_power_train_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_power_train_checklist.py
│ │ │ └── service_power_train_checklist.json
│ │ ├── service_steering_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_steering_checklist.py
│ │ │ └── service_steering_checklist.json
│ │ ├── service_suspension_checklist
│ │ │ ├── __init__.py
│ │ │ ├── service_suspension_checklist.py
│ │ │ └── service_suspension_checklist.json
│ │ ├── service_vehicle_inspection
│ │ │ ├── __init__.py
│ │ │ ├── test_service_vehicle_inspection.py
│ │ │ ├── service_vehicle_inspection.js
│ │ │ ├── service_vehicle_inspection.py
│ │ │ └── service_vehicle_inspection.json
│ │ ├── part_and_consumable_item_group
│ │ │ ├── __init__.py
│ │ │ ├── part_and_consumable_item_group.py
│ │ │ └── part_and_consumable_item_group.json
│ │ ├── service_pre_inspection_template
│ │ │ ├── __init__.py
│ │ │ ├── test_service_pre_inspection_template.py
│ │ │ ├── service_pre_inspection_template.js
│ │ │ ├── service_pre_inspection_template.py
│ │ │ └── service_pre_inspection_template.json
│ │ ├── template_parts_and_consumables
│ │ │ ├── __init__.py
│ │ │ ├── template_parts_and_consumables.py
│ │ │ └── template_parts_and_consumables.json
│ │ └── company_service_management_settings
│ │ │ ├── __init__.py
│ │ │ ├── test_company_service_management_settings.py
│ │ │ ├── company_service_management_settings.js
│ │ │ ├── company_service_management_settings.py
│ │ │ └── company_service_management_settings.json
│ ├── report
│ │ ├── __init__.py
│ │ └── service_job_card_detail
│ │ │ ├── __init__.py
│ │ │ ├── service_job_card_detail.js
│ │ │ ├── service_job_card_detail.json
│ │ │ └── service_job_card_detail.py
│ └── workspace
│ │ └── service
│ │ └── service.json
├── modules.txt
├── __init__.py
├── fixtures
│ ├── custom_field.json
│ └── property_setter.json
└── hooks.py
├── .gitignore
├── README.md
├── .mergify.yml
├── MANIFEST.in
└── setup.py
/license.txt:
--------------------------------------------------------------------------------
1 | License: MIT
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | frappe
--------------------------------------------------------------------------------
/servicems/patches.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/config/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/servicems/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/templates/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/templates/pages/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/report/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/modules.txt:
--------------------------------------------------------------------------------
1 | servicems
2 | Service Management
--------------------------------------------------------------------------------
/servicems/templates/pages/__pycache__/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/complains/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/faults/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/sold_by/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/spare/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/job_card_tasks/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_task/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/supplied_parts/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/template_task/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/vehicle_make/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/vehicle_model/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/job_card_status/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/job_card_template/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/pre_inspection_item/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_job_card/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_parts_entry/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_settings/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_template/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_vehicle/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_workshop/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/job_card_items_supplied/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/parts_and_consumable/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_brake_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_engine_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_tyre_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_vehicle_type/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/report/service_job_card_detail/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_air_system_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_electrical_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_electronics_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_fuel_system_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_lighting_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_parts_entry_detail/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_power_train_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_steering_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_suspension_checklist/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_vehicle_inspection/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/part_and_consumable_item_group/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_pre_inspection_template/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/template_parts_and_consumables/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/company_service_management_settings/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.pyc
3 | *.egg-info
4 | *.swp
5 | tags
6 | servicems/docs/current
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## servicems
2 |
3 | Service Management System for ERPNext
4 |
5 | #### License
6 |
7 | MIT
--------------------------------------------------------------------------------
/servicems/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 |
4 | __version__ = '0.0.1'
5 |
6 |
--------------------------------------------------------------------------------
/.mergify.yml:
--------------------------------------------------------------------------------
1 | pull_request_rules:
2 | - name: Automatic merge on approval
3 | conditions:
4 | - "#approved-reviews-by>=1"
5 | actions:
6 | merge:
7 | method: merge
8 |
--------------------------------------------------------------------------------
/servicems/service_management/doctype/vehicle_model/templates/vehicle_model_row.html:
--------------------------------------------------------------------------------
1 |
\
116 | No any Item selected'
117 | )
118 | });
119 | }
120 | });
121 | d.$wrapper.find('.modal-content').css({
122 | "width": "900px",
123 | "max-height": "1500px",
124 | "overflow-y": "auto",
125 | "display": "table-cell",
126 | "text-align": "left"
127 | });
128 |
129 | d.show();
130 |
131 | } else {
132 | let d = new frappe.ui.Dialog({
133 | title: "Select Items Unbill",
134 | fields: [{fieldname: "html",fieldtype: "HTML"}]
135 | });
136 | d.fields_dict.html.$wrapper.append(`
138 |
139 |
140 |
142 |
143 |
`);
144 | d.show()
145 | };
146 | });
147 | }
148 | }
149 | });
150 |
151 |
152 | const setMatrialBtn = frm => {
153 | if (!frm.is_dirty() && frm.doc.docstatus == 0) {
154 | frm.add_custom_button('Create Stock Entry', () => {
155 | createStockEntry(frm);
156 | });
157 | }
158 | else {
159 | frm.remove_custom_button('Create Stock Entry');
160 | }
161 | };
162 |
163 | const createStockEntry = async function (frm) {
164 | if (frm.is_dirty()) {
165 | await frm.save();
166 | }
167 | frm.call('create_stock_entry', { type: "call" })
168 | .then(r => {
169 | frm.reload_doc();
170 | });
171 | };
172 |
173 | var get_qty_to_return = function(wrapper) {
174 | $.each(wrapper.find("tr:has(input:checkbox)"), function(index, row) {
175 | $(this).on("click", "input:checkbox", function() {
176 | if ($("input:checkbox").is(":checked") == true) {
177 | if ($(this).parent().siblings().last().html() == "") {
178 | $("")
179 | .appendTo($(this).parent().siblings().last());
180 |
181 | $("#return").focusout("input", function() {
182 | let row_qty = $(this).parent().siblings().eq(-2).text();
183 |
184 | if (parseInt($("#return").val()) <= parseInt(row_qty) && parseInt($("#return").val()) > 0) {
185 | // store data to qty_to_return
186 | $(this).parent().siblings().last().attr("data-qty_to_return", $("#return").val())
187 | $("#return").css("border", "1px solid blue");
188 |
189 | } else {
190 | $("#return").css({ "border": "4px solid red", "font-weight": "bold" }).val("");
191 | frappe.msgprint({
192 | title: __('Message'),
193 | indicator: 'red',
194 | message: __(
195 | '\
196 | Qty to return cannot be Negative, cannot be Zero(0) or Empty
\
197 | and cannot be greater than Qty'
198 | )
199 | });
200 | };
201 | });
202 | }
203 | } else {
204 | $(this).parent().siblings().last().html("");
205 | }
206 | });
207 | });
208 | };
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_job_card/service_job_card.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2021, Aakvatech Limited and contributors
2 | # For license information, please see license.txt
3 |
4 | import frappe
5 | from frappe.website.website_generator import WebsiteGenerator
6 | from frappe import _
7 | from frappe.utils import nowdate, nowtime, cint
8 | import json
9 |
10 |
11 | class ServiceJobCard(WebsiteGenerator):
12 | def validate(self):
13 | self.update_tables()
14 | self.set_parts_rate()
15 | self.set_totals()
16 | self.vaildate_complete()
17 |
18 | def before_submit(self):
19 | use_parts_entry = (
20 | frappe.get_value("Company Service Management Settings", "use_parts_entry")
21 | or 0
22 | )
23 | if use_parts_entry:
24 | self.create_parts_entry("before_submit")
25 | else:
26 | self.create_stock_entry("before_submit")
27 | self.create_invoice()
28 |
29 | def on_submit(self):
30 | if self.status != "Completed":
31 | frappe.throw(_("It is not allowed to submit if it is not completed"))
32 |
33 | def update_tables(self):
34 | for template in self.services:
35 | if not template.bypass_billable:
36 | template.is_billable = frappe.get_value(
37 | "Service Template", template.service, "is_billable"
38 | )
39 | if not template.applied:
40 | template_doc = frappe.get_doc("Service Template", template.service)
41 | if template_doc.tasks:
42 | for task in template_doc.tasks:
43 | row = self.append("tasks", {})
44 | row.task_name = task.task_name
45 | row.template = template_doc.name
46 |
47 | if template_doc.parts:
48 | for part in template_doc.parts:
49 | row = self.append("parts", {})
50 | row.item = part.item
51 | row.qty = part.qty
52 | row.rate = get_item_price(
53 | part.item,
54 | self.get_price_list(template_doc.price_list),
55 | self.company,
56 | )
57 | row.is_billable = part.is_billable
58 | template.applied = 1
59 |
60 | def set_totals(self):
61 | self.service_charges = 0
62 | self.spares_cost = 0
63 | self.total = 0
64 |
65 | if self.services:
66 | for service in self.services:
67 | service.rate = get_item_price(
68 | service.item, self.get_price_list(service.price_list), self.company
69 | )
70 | if service.is_billable:
71 | self.service_charges += service.rate
72 | if self.parts:
73 | for part in self.parts:
74 | if part.is_billable:
75 | self.spares_cost += part.rate * part.qty
76 | if self.supplied_parts:
77 | for supplied_part in self.supplied_parts:
78 | if supplied_part.is_billable:
79 | self.spares_cost += supplied_part.rate * supplied_part.qty
80 |
81 | self.total = self.service_charges + self.spares_cost
82 |
83 | def set_parts_rate(self):
84 | price_list = self.get_price_list()
85 | for item in self.parts:
86 | if not item.rate:
87 | item.rate = get_item_price(item.item, price_list, self.company)
88 |
89 | # @frappe.whitelist()
90 | def create_parts_entry(self, type):
91 | if self.parts and len(self.parts) > 0:
92 | items = []
93 | for item in self.parts:
94 | if item.qty > 0:
95 | items.append(
96 | {
97 | "item_code": item.item,
98 | "qty": item.qty,
99 | }
100 | )
101 |
102 | if len(items) == 0:
103 | return
104 |
105 | doc = frappe.get_doc(
106 | dict(
107 | doctype="Service Parts Entry",
108 | posting_date=nowdate(),
109 | posting_time=nowtime(),
110 | company=self.company,
111 | service_job_card=self.name,
112 | items=items,
113 | ),
114 | )
115 | frappe.flags.ignore_account_permission = True
116 | doc.insert(ignore_permissions=True)
117 | doc.submit()
118 | frappe.msgprint(
119 | _("Service Parts Entry Created {0}").format(doc.name), alert=True
120 | )
121 |
122 | if doc.get("name"):
123 | left_parts = []
124 | for row in self.parts:
125 | if row.qty > 0:
126 | new_row = self.append("supplied_parts", {})
127 | new_row.item = row.item
128 | new_row.qty = row.qty
129 | new_row.rate = row.rate
130 | new_row.is_billable = row.is_billable
131 | new_row.stock_entry = doc.name
132 | else:
133 | left_parts.append(row)
134 | self.parts = left_parts
135 | if type == "call":
136 | self.save()
137 |
138 | @frappe.whitelist()
139 | def create_stock_entry(self, type):
140 | if self.parts and len(self.parts) > 0:
141 | workshop = frappe.get_doc("Service Workshop", self.workshop)
142 | items = []
143 | for item in self.parts:
144 | if item.qty > 0:
145 | items.append(
146 | {
147 | "s_warehouse": workshop.parts_warehouse,
148 | "t_warehouse": workshop.workshop_warehouse,
149 | "item_code": item.item,
150 | "qty": item.qty,
151 | "uom": frappe.get_value("Item", item.item, "stock_uom"),
152 | }
153 | )
154 |
155 | if len(items) == 0:
156 | return
157 |
158 | doc = frappe.get_doc(
159 | dict(
160 | doctype="Stock Entry",
161 | posting_date=nowdate(),
162 | posting_time=nowtime(),
163 | stock_entry_type="Material Transfer",
164 | purpose="Material Transfer",
165 | company=self.company,
166 | service_job_card=self.name,
167 | from_warehouse=workshop.parts_warehouse,
168 | to_warehouse=workshop.workshop_warehouse,
169 | items=items,
170 | ),
171 | )
172 | frappe.flags.ignore_account_permission = True
173 | doc.insert(ignore_permissions=True)
174 | doc.submit()
175 | frappe.msgprint(_("Stock Entry Created {0}").format(doc.name), alert=True)
176 |
177 | if doc.get("name"):
178 | left_parts = []
179 | for row in self.parts:
180 | if row.qty > 0:
181 | new_row = self.append("supplied_parts", {})
182 | new_row.item = row.item
183 | new_row.qty = row.qty
184 | new_row.rate = row.rate
185 | new_row.is_billable = row.is_billable
186 | new_row.stock_entry = doc.name
187 | else:
188 | left_parts.append(row)
189 | self.parts = left_parts
190 | if type == "call":
191 | self.save()
192 |
193 | def create_invoice(self):
194 | if self.status != "Completed":
195 | return
196 | items = []
197 | workshop = frappe.get_doc("Service Workshop", self.workshop)
198 | if self.services and len(self.services) > 0:
199 | for item in self.services:
200 | if not item.is_billable:
201 | continue
202 |
203 | items.append(
204 | {
205 | "item_code": item.item,
206 | "qty": 1,
207 | "uom": frappe.get_value("Item", item.item, "stock_uom"),
208 | "warehouse": workshop.workshop_warehouse,
209 | "rate": item.rate if item.is_billable else 0,
210 | }
211 | )
212 | if self.supplied_parts and len(self.supplied_parts) > 0:
213 | for item in self.supplied_parts:
214 | if not item.is_billable or item.is_return or item.qty == 0:
215 | continue
216 |
217 | items.append(
218 | {
219 | "item_code": item.item,
220 | "qty": item.qty,
221 | "uom": frappe.get_value("Item", item.item, "stock_uom"),
222 | "warehouse": workshop.workshop_warehouse,
223 | "rate": item.rate if item.is_billable else 0,
224 | }
225 | )
226 | taxes = frappe.get_value(
227 | "Sales Taxes and Charges Template",
228 | {"company": self.company, "is_default": 1},
229 | ["name", "tax_category"],
230 | as_dict=1,
231 | )
232 |
233 | if len(items) == 0:
234 | return
235 | date = nowdate()
236 | doc = frappe.get_doc(
237 | dict(
238 | doctype="Sales Invoice",
239 | customer=self.customer,
240 | posting_date=date,
241 | due_date=date,
242 | update_stock=1,
243 | service_job_card=self.name,
244 | company=self.company,
245 | ignore_pricing_rule=1,
246 | set_warehouse=workshop.workshop_warehouse,
247 | items=items,
248 | taxes_and_charges=taxes.name,
249 | tax_category=taxes.tax_category,
250 | ),
251 | )
252 | frappe.flags.ignore_account_permission = True
253 | doc.set_taxes()
254 | doc.set_missing_values(for_validate=True)
255 | doc.flags.ignore_mandatory = True
256 | doc.calculate_taxes_and_totals()
257 | doc.insert(ignore_permissions=True)
258 | self.invoice = doc.name
259 | frappe.msgprint(_("Sales Invoice Created {0}").format(doc.name), alert=True)
260 |
261 | def vaildate_complete(self):
262 | if self.status != "Completed":
263 | return
264 | completed = True
265 | for task in self.tasks:
266 | if not task.completed:
267 | completed = False
268 | if not completed:
269 | frappe.throw(_("The Tasks is not Completed"))
270 |
271 | def get_price_list(self, template_price_list=None):
272 | price_list = frappe.get_value("Customer", self.customer, "default_price_list")
273 | if not price_list and template_price_list:
274 | price_list = template_price_list
275 | if not price_list:
276 | price_list = frappe.get_value(
277 | "Service Settings", "Service Settings", "price_list"
278 | )
279 | return price_list or ""
280 |
281 |
282 | def get_item_price(item_code, price_list, company):
283 | price = 0
284 | company_currency = frappe.get_value("Company", company, "default_currency")
285 | item_prices_data = frappe.get_all(
286 | "Item Price",
287 | fields=["item_code", "price_list_rate", "currency"],
288 | filters={
289 | "price_list": price_list,
290 | "item_code": item_code,
291 | "currency": company_currency,
292 | },
293 | order_by="valid_from desc",
294 | )
295 | if len(item_prices_data):
296 | price = item_prices_data[0].price_list_rate or 0
297 | return price
298 |
299 |
300 | @frappe.whitelist()
301 | def get_selected_items(items):
302 | selected_items = json.loads(items)
303 |
304 | if selected_items:
305 | doc = frappe.get_doc(
306 | selected_items[0]["parenttype"], selected_items[0]["parent"]
307 | )
308 | source_doc = frappe.get_doc("Stock Entry", selected_items[0]["stock_entry"])
309 |
310 | new_doc = frappe.new_doc("Stock Entry")
311 | new_doc.company = source_doc.company
312 | new_doc.stock_entry_type = source_doc.stock_entry_type
313 | new_doc.purpose = source_doc.purpose
314 | new_doc.posting_date = nowdate()
315 | new_doc.posting_time = nowtime()
316 | new_doc.from_warehouse = source_doc.to_warehouse
317 | new_doc.to_warehouse = source_doc.from_warehouse
318 | new_doc.is_return = 1
319 | new_doc.service_job_card = doc.name
320 |
321 | for item in selected_items:
322 | if not item.get("qty_to_return"):
323 | frappe.throw(
324 | _(
325 | '\
326 | Can not process stock entry for empty quantity to return'
327 | )
328 | )
329 |
330 | for entry in source_doc.items:
331 | if item.get("item") == entry.item_code:
332 | new_doc.append(
333 | "items",
334 | {
335 | "s_warehouse": entry.t_warehouse,
336 | "t_warehouse": entry.s_warehouse,
337 | "item_code": item.get("item"),
338 | "item_name": entry.item_name,
339 | "description": entry.description,
340 | "item_group": entry.item_group,
341 | "qty": item.get("qty_to_return"),
342 | "transfer_qty": item.get("qty_to_return"),
343 | "uom": entry.uom,
344 | "stock_uom": entry.stock_uom,
345 | "conversion_factor": entry.conversion_factor,
346 | "expense_account": entry.expense_account,
347 | "basic_rate": item.get("rate"),
348 | "basic_amount": item.get("rate"),
349 | "amount": item.get("rate"),
350 | "cost_center": entry.cost_center,
351 | },
352 | )
353 |
354 | new_doc.save(ignore_permissions=True)
355 | new_doc.submit()
356 | if new_doc.get("name"):
357 | updated_supplied_parts(doc, selected_items, new_doc.get("name"))
358 | frappe.msgprint(
359 | "Stock Entry: {0} Created Successfully".format(
360 | frappe.bold(new_doc.name)
361 | )
362 | )
363 | else:
364 | frappe.throw("Stock Entry was not created, try again")
365 |
366 |
367 | def updated_supplied_parts(doc, selected_items, name):
368 | for row in doc.supplied_parts:
369 | if not row.is_billable:
370 | continue
371 | for d in selected_items:
372 | if row.item == d["item"]:
373 | row.qty_returned = d.get("qty_to_return")
374 | row.qty = cint(d.get("qty")) - cint(d.get("qty_to_return"))
375 | row.return_stock_enty = name
376 | if (cint(d.get("qty")) - cint(d.get("qty_to_return"))) == 0:
377 | row.is_billable = 0
378 | row.is_return = 1
379 | doc.save()
380 | doc.reload()
381 |
382 |
383 | @frappe.whitelist()
384 | def get_all_supplied_parts(job_card):
385 | return frappe.get_all("Supplied Parts",
386 | filters={"parent": job_card, "is_billable": 1, "is_return": 0},
387 | fields=["idx", "item", "item_name", "qty", "rate", "stock_entry", "parent", "parenttype"],
388 | order_by = 'idx ASC',
389 | page_length=100
390 | )
--------------------------------------------------------------------------------
/servicems/service_management/doctype/service_job_card/service_job_card.json:
--------------------------------------------------------------------------------
1 | {
2 | "actions": [],
3 | "allow_guest_to_view": 1,
4 | "autoname": "naming_series:",
5 | "creation": "2021-06-24 12:11:22.557561",
6 | "doctype": "DocType",
7 | "editable_grid": 1,
8 | "engine": "InnoDB",
9 | "field_order": [
10 | "status",
11 | "workshop",
12 | "use_spare_not_item",
13 | "column_break_6",
14 | "receiving_datetime",
15 | "naming_series",
16 | "company",
17 | "section_break_7",
18 | "service_item_doctype",
19 | "service_item_name",
20 | "customer",
21 | "mobile_no",
22 | "vehicle_model",
23 | "driver_name",
24 | "driver_mobile_number",
25 | "column_break_11",
26 | "make",
27 | "type",
28 | "engine_number",
29 | "chassis_number",
30 | "odometer_reading",
31 | "vin",
32 | "section_break_11",
33 | "complains",
34 | "section_break_13",
35 | "faults",
36 | "section_break_15",
37 | "services",
38 | "section_break_17",
39 | "tasks",
40 | "section_break_26",
41 | "parts",
42 | "supplied_parts",
43 | "unbill_item",
44 | "section_break_31",
45 | "invoice",
46 | "column_break_38",
47 | "service_charges",
48 | "spares_cost",
49 | "total",
50 | "amended_from",
51 | "route",
52 | "section_break_41",
53 | "service_book",
54 | "cigar_lighter",
55 | "first_aid",
56 | "clock",
57 | "gear_lock",
58 | "tyre_stopper",
59 | "tarpaulin",
60 | "fog_lamps",
61 | "column_break_44",
62 | "fire_extinguisher",
63 | "mobile_charger",
64 | "cargo_belt",
65 | "tool_kit",
66 | "jock",
67 | "pressure_pipe",
68 | "helmet",
69 | "section_break_43",
70 | "battery_make",
71 | "battery_no",
72 | "battery_condition_column",
73 | "excellent",
74 | "good",
75 | "poor",
76 | "tyre_details_section",
77 | "front_left",
78 | "axle_1_rear_left",
79 | "axle_2_rear_left",
80 | "trailer_axle_left_1and2",
81 | "trailer_axle_2_left_1and2",
82 | "trailer_axle_3_left_1and2",
83 | "spare_wheel_1",
84 | "note_section",
85 | "section_break_82",
86 | "data_83",
87 | "column_break_71",
88 | "front_right",
89 | "axle_1_rear_right",
90 | "axle2_rear_right_t_1_and_2",
91 | "trailer_axle_right_1_and_2",
92 | "trailer_axle_2_right_1_and_2",
93 | "trailer_axle_3_right_1_and_2",
94 | "spare_wheel_2",
95 | "section_break_83",
96 | "driver_verbatin_column",
97 | "text_83",
98 | "service_advisor_instructor_column",
99 | "section_break_89",
100 | "parts_description",
101 | "column_break_91",
102 | "parts_no",
103 | "column_break_93",
104 | "total_estimated"
105 | ],
106 | "fields": [
107 | {
108 | "fieldname": "naming_series",
109 | "fieldtype": "Select",
110 | "label": "Naming Series",
111 | "options": "SJC-.YY.-.######"
112 | },
113 | {
114 | "default": "Initiated",
115 | "fieldname": "status",
116 | "fieldtype": "Select",
117 | "in_list_view": 1,
118 | "label": "Status",
119 | "options": "Initiated\nActive\nInspection\nRepairing\nAwaiting Parts\nCompleted\nClosed",
120 | "reqd": 1
121 | },
122 | {
123 | "fetch_from": "workshop.company",
124 | "fieldname": "company",
125 | "fieldtype": "Link",
126 | "in_list_view": 1,
127 | "label": "Company",
128 | "options": "Company",
129 | "read_only": 1,
130 | "reqd": 1
131 | },
132 | {
133 | "fieldname": "workshop",
134 | "fieldtype": "Link",
135 | "in_list_view": 1,
136 | "label": "Workshop",
137 | "options": "Service Workshop",
138 | "reqd": 1
139 | },
140 | {
141 | "fieldname": "column_break_6",
142 | "fieldtype": "Column Break"
143 | },
144 | {
145 | "fieldname": "service_item_doctype",
146 | "fieldtype": "Data",
147 | "hidden": 1,
148 | "label": "Service Item Doctype"
149 | },
150 | {
151 | "fieldname": "service_item_name",
152 | "fieldtype": "Link",
153 | "label": "Service Item Name",
154 | "options": "Service Vehicle",
155 | "reqd": 1
156 | },
157 | {
158 | "fetch_from": "service_item_name.customer",
159 | "fieldname": "customer",
160 | "fieldtype": "Link",
161 | "label": "Customer",
162 | "options": "Customer",
163 | "read_only": 1,
164 | "reqd": 1
165 | },
166 | {
167 | "default": "Now",
168 | "fieldname": "receiving_datetime",
169 | "fieldtype": "Datetime",
170 | "in_list_view": 1,
171 | "label": "Receiving DateTime",
172 | "reqd": 1
173 | },
174 | {
175 | "fieldname": "section_break_11",
176 | "fieldtype": "Section Break"
177 | },
178 | {
179 | "fieldname": "complains",
180 | "fieldtype": "Table",
181 | "label": "Complains",
182 | "options": "Complains",
183 | "reqd": 1
184 | },
185 | {
186 | "fieldname": "section_break_13",
187 | "fieldtype": "Section Break"
188 | },
189 | {
190 | "fieldname": "faults",
191 | "fieldtype": "Table",
192 | "label": "Faults",
193 | "options": "Faults"
194 | },
195 | {
196 | "fieldname": "section_break_15",
197 | "fieldtype": "Section Break"
198 | },
199 | {
200 | "fieldname": "section_break_17",
201 | "fieldtype": "Section Break"
202 | },
203 | {
204 | "fieldname": "section_break_7",
205 | "fieldtype": "Section Break"
206 | },
207 | {
208 | "fieldname": "column_break_11",
209 | "fieldtype": "Column Break"
210 | },
211 | {
212 | "fetch_from": "service_item_name.vehicle_model",
213 | "fieldname": "vehicle_model",
214 | "fieldtype": "Data",
215 | "label": "Vehicle Model",
216 | "read_only": 1
217 | },
218 | {
219 | "fetch_from": "service_item_name.make",
220 | "fieldname": "make",
221 | "fieldtype": "Data",
222 | "label": "Make",
223 | "read_only": 1
224 | },
225 | {
226 | "fetch_from": "service_item_name.type",
227 | "fieldname": "type",
228 | "fieldtype": "Data",
229 | "label": "Type",
230 | "read_only": 1
231 | },
232 | {
233 | "fetch_from": "service_item_name.engine_number",
234 | "fieldname": "engine_number",
235 | "fieldtype": "Data",
236 | "label": "Engine Number",
237 | "read_only": 1
238 | },
239 | {
240 | "fetch_from": "service_item_name.chassis_number",
241 | "fieldname": "chassis_number",
242 | "fieldtype": "Data",
243 | "label": "Chassis Number",
244 | "read_only": 1
245 | },
246 | {
247 | "fieldname": "section_break_26",
248 | "fieldtype": "Section Break"
249 | },
250 | {
251 | "fieldname": "service_charges",
252 | "fieldtype": "Currency",
253 | "label": "Service Charges",
254 | "read_only": 1
255 | },
256 | {
257 | "fieldname": "spares_cost",
258 | "fieldtype": "Currency",
259 | "label": "Spares Cost",
260 | "read_only": 1
261 | },
262 | {
263 | "fieldname": "total",
264 | "fieldtype": "Currency",
265 | "label": "Total Excl. Vat",
266 | "read_only": 1
267 | },
268 | {
269 | "fieldname": "column_break_38",
270 | "fieldtype": "Column Break"
271 | },
272 | {
273 | "fieldname": "section_break_31",
274 | "fieldtype": "Section Break"
275 | },
276 | {
277 | "fieldname": "invoice",
278 | "fieldtype": "Link",
279 | "label": "Invoice Number",
280 | "options": "Sales Invoice"
281 | },
282 | {
283 | "fieldname": "services",
284 | "fieldtype": "Table",
285 | "label": "Service Task Templates",
286 | "options": "Job Card Template",
287 | "reqd": 1
288 | },
289 | {
290 | "allow_bulk_edit": 1,
291 | "fieldname": "parts",
292 | "fieldtype": "Table",
293 | "label": "Parts and Consumable Supplied",
294 | "options": "Job Card Items Supplied"
295 | },
296 | {
297 | "fieldname": "tasks",
298 | "fieldtype": "Table",
299 | "label": "Task",
300 | "options": "Job Card Tasks"
301 | },
302 | {
303 | "fieldname": "amended_from",
304 | "fieldtype": "Link",
305 | "label": "Amended From",
306 | "no_copy": 1,
307 | "options": "Service Job Card",
308 | "print_hide": 1,
309 | "read_only": 1
310 | },
311 | {
312 | "fieldname": "route",
313 | "fieldtype": "Data",
314 | "label": "Route"
315 | },
316 | {
317 | "fetch_from": "customer.mobile_no",
318 | "fieldname": "mobile_no",
319 | "fieldtype": "Data",
320 | "label": "Mobile No",
321 | "read_only": 1
322 | },
323 | {
324 | "fieldname": "supplied_parts",
325 | "fieldtype": "Table",
326 | "label": "Supplied Parts",
327 | "options": "Supplied Parts",
328 | "read_only": 1
329 | },
330 | {
331 | "fieldname": "unbill_item",
332 | "fieldtype": "Button",
333 | "label": "Unbill Item",
334 | "permlevel": 1
335 | },
336 | {
337 | "fieldname": "driver_name",
338 | "fieldtype": "Data",
339 | "label": "Driver Name"
340 | },
341 | {
342 | "fieldname": "driver_mobile_number",
343 | "fieldtype": "Data",
344 | "label": "Driver Mobile Number",
345 | "options": "Phone"
346 | },
347 | {
348 | "fieldname": "odometer_reading",
349 | "fieldtype": "Data",
350 | "label": "Odometer Reading"
351 | },
352 | {
353 | "fieldname": "section_break_41",
354 | "fieldtype": "Section Break",
355 | "label": "Pre Acceptance Inspection"
356 | },
357 | {
358 | "fieldname": "section_break_43",
359 | "fieldtype": "Section Break",
360 | "label": "Battery Details"
361 | },
362 | {
363 | "fetch_from": "service_item_name.vin",
364 | "fieldname": "vin",
365 | "fieldtype": "Data",
366 | "label": "VIN",
367 | "read_only": 1
368 | },
369 | {
370 | "default": "0",
371 | "fieldname": "service_book",
372 | "fieldtype": "Check",
373 | "label": "Service Book"
374 | },
375 | {
376 | "fieldname": "column_break_44",
377 | "fieldtype": "Column Break"
378 | },
379 | {
380 | "default": "0",
381 | "fieldname": "fire_extinguisher",
382 | "fieldtype": "Check",
383 | "label": "Fire Extinguisher"
384 | },
385 | {
386 | "fieldname": "battery_make",
387 | "fieldtype": "Data",
388 | "label": "Battery Make"
389 | },
390 | {
391 | "fieldname": "battery_no",
392 | "fieldtype": "Data",
393 | "label": "Battery No"
394 | },
395 | {
396 | "fieldname": "tyre_details_section",
397 | "fieldtype": "Section Break",
398 | "label": "Tyre Details"
399 | },
400 | {
401 | "fieldname": "front_right",
402 | "fieldtype": "Select",
403 | "label": "Front Right",
404 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
405 | },
406 | {
407 | "fieldname": "front_left",
408 | "fieldtype": "Select",
409 | "label": "Front Left",
410 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
411 | },
412 | {
413 | "fieldname": "axle_1_rear_right",
414 | "fieldtype": "Select",
415 | "label": "AXLE 1 REAR RIGHT T 1 AND 2",
416 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
417 | },
418 | {
419 | "fieldname": "axle_1_rear_left",
420 | "fieldtype": "Select",
421 | "label": "AXLE 1 REAR LEFT T 1 AND 2",
422 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
423 | },
424 | {
425 | "fieldname": "axle_2_rear_left",
426 | "fieldtype": "Select",
427 | "label": "AXLE 2 REAR LEFT T 1 AND 2",
428 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
429 | },
430 | {
431 | "fieldname": "spare_wheel_1",
432 | "fieldtype": "Select",
433 | "label": "Spare Wheel 1",
434 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
435 | },
436 | {
437 | "fieldname": "spare_wheel_2",
438 | "fieldtype": "Select",
439 | "label": "Spare Wheel 2",
440 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
441 | },
442 | {
443 | "default": "0",
444 | "fieldname": "cigar_lighter",
445 | "fieldtype": "Check",
446 | "label": "Cigar Lighter"
447 | },
448 | {
449 | "default": "0",
450 | "fieldname": "first_aid",
451 | "fieldtype": "Check",
452 | "label": "First aid"
453 | },
454 | {
455 | "default": "0",
456 | "fieldname": "clock",
457 | "fieldtype": "Check",
458 | "label": "Clock"
459 | },
460 | {
461 | "default": "0",
462 | "fieldname": "gear_lock",
463 | "fieldtype": "Check",
464 | "label": "Gear Lock"
465 | },
466 | {
467 | "default": "0",
468 | "fieldname": "tyre_stopper",
469 | "fieldtype": "Check",
470 | "label": "Tyre stopper"
471 | },
472 | {
473 | "default": "0",
474 | "fieldname": "tarpaulin",
475 | "fieldtype": "Check",
476 | "label": "Tarpaulin"
477 | },
478 | {
479 | "default": "0",
480 | "fieldname": "fog_lamps",
481 | "fieldtype": "Check",
482 | "label": "Fog Lamp"
483 | },
484 | {
485 | "default": "0",
486 | "fieldname": "mobile_charger",
487 | "fieldtype": "Check",
488 | "label": "Mobile Charger"
489 | },
490 | {
491 | "default": "0",
492 | "fieldname": "cargo_belt",
493 | "fieldtype": "Check",
494 | "label": "Cargo belt"
495 | },
496 | {
497 | "default": "0",
498 | "fieldname": "tool_kit",
499 | "fieldtype": "Check",
500 | "label": "Tool Kit"
501 | },
502 | {
503 | "default": "0",
504 | "fieldname": "jock",
505 | "fieldtype": "Check",
506 | "label": "Jock"
507 | },
508 | {
509 | "default": "0",
510 | "fieldname": "pressure_pipe",
511 | "fieldtype": "Check",
512 | "label": "Pressure pipe"
513 | },
514 | {
515 | "default": "0",
516 | "fieldname": "helmet",
517 | "fieldtype": "Check",
518 | "label": "Helmet"
519 | },
520 | {
521 | "bold": 1,
522 | "fieldname": "battery_condition_column",
523 | "fieldtype": "Column Break",
524 | "label": "Battery Condition"
525 | },
526 | {
527 | "default": "0",
528 | "fieldname": "excellent",
529 | "fieldtype": "Check",
530 | "label": "Excellent"
531 | },
532 | {
533 | "default": "0",
534 | "fieldname": "good",
535 | "fieldtype": "Check",
536 | "label": "Good"
537 | },
538 | {
539 | "default": "0",
540 | "fieldname": "poor",
541 | "fieldtype": "Check",
542 | "label": "Poor"
543 | },
544 | {
545 | "fieldname": "note_section",
546 | "fieldtype": "Read Only",
547 | "label": "Note To Measure Tyre tread use Tread DepthGuage"
548 | },
549 | {
550 | "bold": 1,
551 | "fieldname": "driver_verbatin_column",
552 | "fieldtype": "Small Text",
553 | "label": "Driver Verbatin"
554 | },
555 | {
556 | "fieldname": "service_advisor_instructor_column",
557 | "fieldtype": "Small Text",
558 | "label": "Service Advisor Instructor"
559 | },
560 | {
561 | "fieldname": "text_83",
562 | "fieldtype": "Column Break"
563 | },
564 | {
565 | "bold": 1,
566 | "fieldname": "section_break_82",
567 | "fieldtype": "Heading",
568 | "label": "Remark/Vehicles diagnosis report"
569 | },
570 | {
571 | "fieldname": "section_break_83",
572 | "fieldtype": "Section Break"
573 | },
574 | {
575 | "fieldname": "data_83",
576 | "fieldtype": "Data"
577 | },
578 | {
579 | "fieldname": "column_break_71",
580 | "fieldtype": "Column Break"
581 | },
582 | {
583 | "fieldname": "trailer_axle_left_1and2",
584 | "fieldtype": "Select",
585 | "label": "TRAILER AXLE LEFT 1 AND 2",
586 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
587 | },
588 | {
589 | "fieldname": "trailer_axle_2_left_1and2",
590 | "fieldtype": "Select",
591 | "label": "TRAILER AXLE 2 LEFT 1 AND 2",
592 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
593 | },
594 | {
595 | "fieldname": "trailer_axle_3_left_1and2",
596 | "fieldtype": "Select",
597 | "label": "TRAILER AXLE 3 LEFT 1 AND 2",
598 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
599 | },
600 | {
601 | "fieldname": "axle2_rear_right_t_1_and_2",
602 | "fieldtype": "Select",
603 | "label": "AXLE2 REAR RIGHT T 1 AND 2",
604 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
605 | },
606 | {
607 | "fieldname": "trailer_axle_right_1_and_2",
608 | "fieldtype": "Select",
609 | "label": "TRAILER AXLE RIGHT 1 AND 2",
610 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
611 | },
612 | {
613 | "fieldname": "trailer_axle_2_right_1_and_2",
614 | "fieldtype": "Select",
615 | "label": "TRAILER AXLE 2 RIGHT 1 AND 2",
616 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
617 | },
618 | {
619 | "fieldname": "trailer_axle_3_right_1_and_2",
620 | "fieldtype": "Select",
621 | "label": "TRAILER AXLE 3 RIGHT 1 AND 2",
622 | "options": "\nAbove 10 mm\nAround 7 mm\nLess than 2.6 mm"
623 | },
624 | {
625 | "fieldname": "section_break_89",
626 | "fieldtype": "Section Break",
627 | "label": "Estimated Repair"
628 | },
629 | {
630 | "bold": 1,
631 | "fieldname": "parts_description",
632 | "fieldtype": "Small Text",
633 | "label": "Part Description"
634 | },
635 | {
636 | "fieldname": "column_break_91",
637 | "fieldtype": "Column Break"
638 | },
639 | {
640 | "fieldname": "parts_no",
641 | "fieldtype": "Small Text",
642 | "label": "Part No"
643 | },
644 | {
645 | "fieldname": "column_break_93",
646 | "fieldtype": "Column Break"
647 | },
648 | {
649 | "default": "0",
650 | "fetch_from": "workshop.use_spare_not_item",
651 | "fieldname": "use_spare_not_item",
652 | "fieldtype": "Check",
653 | "label": "Use Spare Not Item",
654 | "read_only": 1
655 | },
656 | {
657 | "fieldname": "total_estimated",
658 | "fieldtype": "Currency",
659 | "label": "Total"
660 | }
661 | ],
662 | "has_web_view": 1,
663 | "index_web_pages_for_search": 1,
664 | "is_submittable": 1,
665 | "links": [
666 | {
667 | "link_doctype": "Sales Invoice",
668 | "link_fieldname": "service_job_card"
669 | }
670 | ],
671 | "modified": "2022-11-29 12:50:03.913615",
672 | "modified_by": "Administrator",
673 | "module": "Service Management",
674 | "name": "Service Job Card",
675 | "owner": "Administrator",
676 | "permissions": [
677 | {
678 | "amend": 1,
679 | "cancel": 1,
680 | "create": 1,
681 | "delete": 1,
682 | "email": 1,
683 | "export": 1,
684 | "print": 1,
685 | "read": 1,
686 | "report": 1,
687 | "role": "System Manager",
688 | "share": 1,
689 | "submit": 1,
690 | "write": 1
691 | }
692 | ],
693 | "route": "job-card",
694 | "sort_field": "modified",
695 | "sort_order": "DESC",
696 | "track_changes": 1
697 | }
--------------------------------------------------------------------------------