From 55544e5fe6076a3ed9d02d6155222e4944c39250 Mon Sep 17 00:00:00 2001 From: Emanuel Kagombora Date: Sun, 19 Apr 2026 22:17:21 +0300 Subject: [PATCH 01/18] chore(csf_tz): remove Trip Sheet, Trip Sheet References, and Trip Sheet Item Reference --- csf_tz/csf_tz/doctype/trip_sheet/__init__.py | 0 .../doctype/trip_sheet/test_trip_sheet.py | 9 - .../csf_tz/doctype/trip_sheet/trip_sheet.js | 129 ------------- .../csf_tz/doctype/trip_sheet/trip_sheet.json | 180 ------------------ .../csf_tz/doctype/trip_sheet/trip_sheet.py | 102 ---------- .../trip_sheet_item_reference/__init__.py | 0 .../trip_sheet_item_reference.json | 66 ------- .../trip_sheet_item_reference.py | 9 - .../doctype/trip_sheet_references/__init__.py | 0 .../trip_sheet_references.json | 56 ------ .../trip_sheet_references.py | 9 - 11 files changed, 560 deletions(-) delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet/test_trip_sheet.py delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.js delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.json delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.py delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet_item_reference/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.json delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.py delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet_references/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.json delete mode 100644 csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.py diff --git a/csf_tz/csf_tz/doctype/trip_sheet/__init__.py b/csf_tz/csf_tz/doctype/trip_sheet/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/trip_sheet/test_trip_sheet.py b/csf_tz/csf_tz/doctype/trip_sheet/test_trip_sheet.py deleted file mode 100644 index fe2fd23b..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet/test_trip_sheet.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestTripSheet(FrappeTestCase): - pass diff --git a/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.js b/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.js deleted file mode 100644 index 255c922a..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.js +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2025, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on("Trip Sheet", { - refresh: function (frm) { - // Dynamically set required fields if status is Completed - frm.set_df_property("end_km", "reqd", frm.doc.status === "Completed"); - frm.set_df_property( - "fuel_consumed", - "reqd", - frm.doc.status === "Completed" - ); - - // Set query for reference_doctype in child table - frm.fields_dict["trip_sheet_reference"].grid.get_field( - "reference_doctype" - ).get_query = function (doc, cdt, cdn) { - return { - filters: [ - [ - "name", - "in", - [ - "Purchase Order", - "Delivery Note", - "Purchase Receipt", - "Purchase Invoice", - "Sales Order", - "Stock Entry", - ], - ], - ], - }; - }; - }, - - status: function (frm) { - // When status changes, update required fields - frm.set_df_property("end_km", "reqd", frm.doc.status === "Completed"); - frm.set_df_property( - "fuel_consumed", - "reqd", - frm.doc.status === "Completed" - ); - }, - - driver: function (frm) { - if (frm.doc.driver) { - frappe.db.get_value( - "Employee", - frm.doc.driver, - "employee_name", - function (r) { - frm.set_value("driver_name", r.employee_name); - } - ); - } else { - frm.set_value("driver_name", ""); - } - }, - - // Custom function to fetch items from selected reference documents - fetch_reference_items: function (frm) { - // Clear the table first - frm.clear_table("item_reference"); - - // Loop through trip_sheet_reference child table - (frm.doc.trip_sheet_reference || []).forEach(function (row) { - if (row.reference_doctype && row.reference_document) { - frappe.call({ - method: - "csf_tz.csf_tz.doctype.trip_sheet.trip_sheet.get_reference_items", - args: { - reference_doctype: row.reference_doctype, - reference_document: row.reference_document, - }, - callback: function (r) { - if (r.message && Array.isArray(r.message)) { - // Add all items for this reference doc - r.message.forEach(function (item) { - // Add child and set reference_doctype first - var child = frm.add_child("item_reference"); - child.reference_doctype = row.reference_doctype; - // then set the dynamic link field - child.reference_document_id = row.reference_document; - child.item_name = item.item_name; - child.qty = item.qty; - child.amount = item.amount; - }); - // refresh once after adding items - frm.refresh_field("item_reference"); - } - }, - }); - } - }); - }, -}); - -// For filtering Stock Entry by stock_entry_type, update the handler to use the renamed child doctype -frappe.ui.form.on("Trip Sheet References", { - reference_doctype: function (frm, cdt, cdn) { - var child = locals[cdt][cdn]; - if (child.reference_doctype === "Stock Entry") { - frappe.meta.get_docfield( - "Trip Sheet References", - "reference_document", - frm.doc.name - ).get_query = function () { - return { - filters: { - stock_entry_type: "Material Issue", - }, - }; - }; - } else { - frappe.meta.get_docfield( - "Trip Sheet References", - "reference_document", - frm.doc.name - ).get_query = null; - } - }, - - // Trigger fetch when reference_document changes - reference_document: function (frm, cdt, cdn) { - frm.trigger("fetch_reference_items"); - }, -}); diff --git a/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.json b/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.json deleted file mode 100644 index 7d371a9b..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.json +++ /dev/null @@ -1,180 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "autoname": "TS-.vehicle.-.####", - "creation": "2025-10-04 12:09:25.744664", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "section_break_6a9a", - "amended_from", - "vehicle", - "transporter_type", - "driver", - "driver_name", - "external_driver_name", - "start_km", - "end_km", - "fuel_consumed", - "column_break_bdjc", - "status", - "start_location", - "end_location", - "start_time", - "end_time", - "section_break_pqtf", - "trip_sheet_reference", - "item_reference" - ], - "fields": [ - { - "fieldname": "section_break_6a9a", - "fieldtype": "Section Break" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Trip Sheet", - "print_hide": 1, - "read_only": 1, - "search_index": 1 - }, - { - "fieldname": "vehicle", - "fieldtype": "Link", - "label": "Vehicle", - "options": "Vehicle" - }, - { - "fieldname": "transporter_type", - "fieldtype": "Select", - "label": "Transporter Type", - "options": "Internal Transporter\nExternal Transporter" - }, - { - "fieldname": "driver", - "fieldtype": "Link", - "label": "Driver", - "options": "Employee", - "depends_on": "eval:doc.transporter_type=='Internal Transporter'" - }, - { - "fieldname": "driver_name", - "fieldtype": "Data", - "label": "Driver Name", - "fetch_from": "driver.employee_name", - "depends_on": "eval:doc.transporter_type=='Internal Transporter'" - }, - { - "fieldname": "external_driver_name", - "fieldtype": "Data", - "label": "External Driver Name", - "depends_on": "eval:doc.transporter_type=='External Transporter'" - }, - { - "fieldname": "start_location", - "fieldtype": "Data", - "label": "Start Location" - }, - { - "fieldname": "start_km", - "fieldtype": "Float", - "label": "Start KM" - }, - { - "fieldname": "end_km", - "fieldtype": "Float", - "label": "End KM" - }, - { - "fieldname": "fuel_consumed", - "fieldtype": "Float", - "label": "Fuel Consumed" - }, - { - "fieldname": "status", - "fieldtype": "Select", - "label": "Status", - "options": "Draft\nIn Transit\nCompleted" - }, - { - "fieldname": "column_break_bdjc", - "fieldtype": "Column Break" - }, - { - "fieldname": "end_location", - "fieldtype": "Data", - "label": "End Location" - }, - { - "fieldname": "start_time", - "fieldtype": "Datetime", - "label": "Start Time" - }, - { - "fieldname": "end_time", - "fieldtype": "Datetime", - "label": "End Time" - }, - { - "fieldname": "trip_sheet_reference", - "fieldtype": "Table", - "label": "Trip sheet Reference", - "options": "Trip Sheet References" - }, - { - "fieldname": "item_reference", - "fieldtype": "Table", - "label": "Item Reference", - "options": "Trip Sheet Item Reference", - "read_only": 1 - }, - { - "fieldname": "section_break_pqtf", - "fieldtype": "Section Break" - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "is_submittable": 1, - "links": [], - "modified": "2025-10-08 15:39:25.097234", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Trip Sheet", - "naming_rule": "Expression (old style)", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Logistic Master", - "share": 1, - "submit": 1, - "write": 1 - } - ], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} diff --git a/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.py b/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.py deleted file mode 100644 index 117a3a37..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet/trip_sheet.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt -import frappe -from frappe import _ -from frappe.model.document import Document - - -class TripSheet(Document): - def validate(self): - # If status set to Completed in form, ensure required fields are present. - if getattr(self, "status", None) == "Completed": - if not getattr(self, "end_km", None): - frappe.throw(_("End KM must be filled when status is 'Completed'.")) - if not getattr(self, "fuel_consumed", None): - frappe.throw(_("Fuel Consumed must be filled when status is 'Completed'.")) - - def before_submit(self): - # Final checks before submit - if getattr(self, "status", None) != "Completed": - frappe.throw(_("Trip status must be 'Completed' before submitting.")) - if not getattr(self, "end_km", None): - frappe.throw(_("End KM must be filled before submitting.")) - if not getattr(self, "fuel_consumed", None): - frappe.throw(_("Fuel Consumed must be filled before submitting.")) - - def before_save(self): - # Keep item_reference in sync on save - self.set_item_reference_table() - - def set_item_reference_table(self): - """ - Rebuild the item_reference child table from trip_sheet_reference child table. - Uses fields: - - trip_sheet_reference[].reference_doctype - - trip_sheet_reference[].reference_document - Appends rows to item_reference with fields: - - reference_doctype - - reference_document_id - - item_name - - qty - - amount - """ - self.set("item_reference", []) - - for row in self.get("trip_sheet_reference") or []: - ref_doctype = row.get("reference_doctype") - ref_doc = row.get("reference_document") - if not (ref_doctype and ref_doc): - continue - - items = get_reference_items(ref_doctype, ref_doc) or [] - for it in items: - self.append("item_reference", { - "reference_doctype": ref_doctype, - "reference_document_id": ref_doc, - "item_name": it.get("item_name") or "", - "qty": it.get("qty") or 0, - "amount": it.get("amount") or 0, - }) - - -@frappe.whitelist() -def get_reference_items(reference_doctype, reference_document): - """ - Return list of dicts: { item_name, qty, amount } for the given reference. - Accepts reference_document (string id) to match JS. - """ - items = [] - if reference_doctype not in [ - "Purchase Order", - "Delivery Note", - "Purchase Receipt", - "Purchase Invoice", - "Sales Order", - "Stock Entry", - ]: - return items - - try: - doc = frappe.get_doc(reference_doctype, reference_document) - except Exception: - return items - - for i in getattr(doc, "items", []) or []: - amount = getattr(i, "amount", None) - if amount is None: - amount = getattr(i, "base_amount", None) - # qty fallback: qty or transfer_qty or delivered_qty - qty = getattr(i, "qty", None) - if qty is None: - qty = getattr(i, "transfer_qty", None) - if qty is None: - qty = getattr(i, "delivered_qty", 0) - item_name = getattr(i, "item_name", None) or getattr(i, "item_code", "") - - items.append({ - "item_name": item_name, - "qty": qty or 0, - "amount": amount or 0 - }) - - return items diff --git a/csf_tz/csf_tz/doctype/trip_sheet_item_reference/__init__.py b/csf_tz/csf_tz/doctype/trip_sheet_item_reference/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.json b/csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.json deleted file mode 100644 index a40a7e5f..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "creation": "2025-10-15 18:07:27.398988", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "reference_doctype", - "reference_document_id", - "item_name", - "qty", - "amount" - ], - "fields": [ - { - "fieldname": "reference_doctype", - "fieldtype": "Select", - "label": "Reference Doctype", - "options": "Purchase Order\nDelivery Note\nPurchase Receipt\nPurchase Invoice\nSales Order\nStock Entry", - "read_only": 1 - }, - { - "fieldname": "reference_document_id", - "fieldtype": "Dynamic Link", - "label": "Reference Document ID", - "options": "reference_doctype", - "read_only": 1 - }, - { - "fieldname": "item_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Item Name", - "read_only": 1 - }, - { - "fieldname": "qty", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Quantity", - "read_only": 1 - }, - { - "fieldname": "amount", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Amount", - "read_only": 1 - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2025-10-15 18:16:55.455472", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Trip Sheet Item Reference", - "owner": "Administrator", - "permissions": [], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} diff --git a/csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.py b/csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.py deleted file mode 100644 index dc30190d..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet_item_reference/trip_sheet_item_reference.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class TripSheetItemReference(Document): - pass diff --git a/csf_tz/csf_tz/doctype/trip_sheet_references/__init__.py b/csf_tz/csf_tz/doctype/trip_sheet_references/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.json b/csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.json deleted file mode 100644 index 3aba0cb9..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "creation": "2025-10-04 12:35:30.189065", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "reference_doctype", - "reference_document", - "part_name", - "note" - ], - "fields": [ - { - "fieldname": "note", - "fieldtype": "Small Text", - "in_list_view": 1, - "label": "Note" - }, - { - "fieldname": "reference_doctype", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Reference Doctype", - "options": "DocType" - }, - { - "fieldname": "reference_document", - "fieldtype": "Dynamic Link", - "in_list_view": 1, - "label": "Reference Document", - "options": "reference_doctype" - }, - { - "fieldname": "part_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Part Name" - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2025-10-10 18:08:51.760148", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Trip Sheet References", - "owner": "Administrator", - "permissions": [], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.py b/csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.py deleted file mode 100644 index a2a3fef5..00000000 --- a/csf_tz/csf_tz/doctype/trip_sheet_references/trip_sheet_references.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class TripSheetReferences(Document): - pass From 6776dad952997b1d0759831cd58ff77396f69215 Mon Sep 17 00:00:00 2001 From: Emanuel Kagombora Date: Sun, 19 Apr 2026 22:30:16 +0300 Subject: [PATCH 02/18] chore(csf_tz): remove vehicle sync and consignment doctypes --- .../doctype/vehicle_consignment/__init__.py | 0 .../test_vehicle_consignment.py | 10 - .../vehicle_consignment.js | 8 - .../vehicle_consignment.json | 77 -- .../vehicle_consignment.py | 10 - .../vehicle_consignment_detail/__init__.py | 0 .../vehicle_consignment_detail.json | 32 - .../vehicle_consignment_detail.py | 10 - .../vehicle_inspection_record/__init__.py | 0 .../test_vehicle_inspection_record.py | 9 - .../vehicle_inspection_record.js | 8 - .../vehicle_inspection_record.json | 340 -------- .../vehicle_inspection_record.py | 9 - .../doctype/vehicle_location_log/__init__.py | 0 .../test_vehicle_location_log.py | 9 - .../vehicle_location_log.js | 8 - .../vehicle_location_log.json | 125 --- .../vehicle_location_log.py | 65 -- .../doctype/vehicle_sync_task/__init__.py | 0 .../doctype/vehicle_sync_task/processor.py | 768 ------------------ .../csf_tz/doctype/vehicle_sync_task/queue.py | 162 ---- .../test_vehicle_sync_task.py | 9 - .../vehicle_sync_task/vehicle_sync_task.js | 8 - .../vehicle_sync_task/vehicle_sync_task.json | 178 ---- .../vehicle_sync_task/vehicle_sync_task.py | 13 - csf_tz/hooks.py | 6 - csf_tz/patches.txt | 2 +- .../add_vehicle_sync_task_log_setting.py | 15 - .../remove_vehicle_sync_task_log_setting.py | 17 + 29 files changed, 18 insertions(+), 1880 deletions(-) delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment/test_vehicle_consignment.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.js delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.json delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment_detail/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.json delete mode 100644 csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_inspection_record/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_inspection_record/test_vehicle_inspection_record.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.js delete mode 100644 csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.json delete mode 100644 csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_location_log/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_location_log/test_vehicle_location_log.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.js delete mode 100644 csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.json delete mode 100644 csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_sync_task/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_sync_task/processor.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_sync_task/queue.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_sync_task/test_vehicle_sync_task.py delete mode 100644 csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.js delete mode 100644 csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.json delete mode 100644 csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.py delete mode 100644 csf_tz/patches/add_vehicle_sync_task_log_setting.py create mode 100644 csf_tz/patches/remove_vehicle_sync_task_log_setting.py diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment/__init__.py b/csf_tz/csf_tz/doctype/vehicle_consignment/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment/test_vehicle_consignment.py b/csf_tz/csf_tz/doctype/vehicle_consignment/test_vehicle_consignment.py deleted file mode 100644 index 8fc1d42c..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_consignment/test_vehicle_consignment.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and Contributors -# See license.txt -from __future__ import unicode_literals - -# import frappe -import unittest - -class TestVehicleConsignment(unittest.TestCase): - pass diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.js b/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.js deleted file mode 100644 index 23025124..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2021, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Vehicle Consignment', { - // refresh: function(frm) { - - // } -}); diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.json b/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.json deleted file mode 100644 index 72d0f887..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "actions": [], - "autoname": "VCONS-.YYYY.-.###", - "creation": "2021-01-19 11:24:49.205307", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "parent_item", - "column_break_2", - "quantity", - "section_break_5", - "vehicle_consignment_detail", - "amended_from" - ], - "fields": [ - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "parent_item", - "fieldtype": "Link", - "label": "Parent Item", - "options": "Item" - }, - { - "fieldname": "quantity", - "fieldtype": "Int", - "label": "Quantity" - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break" - }, - { - "fieldname": "vehicle_consignment_detail", - "fieldtype": "Table", - "label": "Vehicle Consignment Detail", - "options": "Vehicle Consignment Detail" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Vehicle Consignment", - "print_hide": 1, - "read_only": 1 - } - ], - "index_web_pages_for_search": 1, - "is_submittable": 1, - "links": [], - "modified": "2021-01-19 11:34:41.517181", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Vehicle Consignment", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.py b/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.py deleted file mode 100644 index 4957bfc9..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_consignment/vehicle_consignment.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -# import frappe -from frappe.model.document import Document - -class VehicleConsignment(Document): - pass diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment_detail/__init__.py b/csf_tz/csf_tz/doctype/vehicle_consignment_detail/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.json b/csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.json deleted file mode 100644 index fbcb6aaf..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "actions": [], - "creation": "2021-01-19 11:24:20.882509", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "bom" - ], - "fields": [ - { - "fieldname": "bom", - "fieldtype": "Link", - "in_list_view": 1, - "label": "BOM", - "options": "BOM" - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2021-01-19 11:24:20.882509", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Vehicle Consignment Detail", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.py b/csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.py deleted file mode 100644 index 25d88e48..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_consignment_detail/vehicle_consignment_detail.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -# import frappe -from frappe.model.document import Document - -class VehicleConsignmentDetail(Document): - pass diff --git a/csf_tz/csf_tz/doctype/vehicle_inspection_record/__init__.py b/csf_tz/csf_tz/doctype/vehicle_inspection_record/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/vehicle_inspection_record/test_vehicle_inspection_record.py b/csf_tz/csf_tz/doctype/vehicle_inspection_record/test_vehicle_inspection_record.py deleted file mode 100644 index 076e9deb..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_inspection_record/test_vehicle_inspection_record.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestVehicleInspectionRecord(FrappeTestCase): - pass diff --git a/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.js b/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.js deleted file mode 100644 index d032b3a2..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2025, Aakvatech and contributors -// For license information, please see license.txt - -// frappe.ui.form.on("Vehicle Inspection Record", { -// refresh(frm) { - -// }, -// }); diff --git a/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.json b/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.json deleted file mode 100644 index 6b345936..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.json +++ /dev/null @@ -1,340 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "autoname": "field:vir_no", - "creation": "2025-09-01 23:06:46.649431", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "vir_no", - "inspection_id", - "vid", - "noplate", - "licence", - "vehicle_doc", - "section_break_1", - "inspection_date", - "valid_until", - "final_result", - "section_break_2", - "inspector", - "inspector_id", - "email", - "column_break_1", - "region", - "district", - "section_break_3", - "driver_name", - "driver_address", - "vehicle_passed_for", - "column_break_2", - "weight", - "prohibition_on_use", - "originates", - "section_break_4", - "speed_test", - "electrical_system", - "fitting_equipment", - "braking_system", - "column_break_3", - "wheels", - "suspension", - "steering", - "engine", - "section_break_5", - "exhaust", - "transmission", - "instruments_panel", - "dimensions", - "radiation", - "section_break_6", - "remarks", - "created_at", - "updated_at" - ], - "fields": [ - { - "fieldname": "vir_no", - "fieldtype": "Data", - "label": "VIR Number", - "reqd": 1, - "unique": 1, - "in_list_view": 1 - }, - { - "fieldname": "inspection_id", - "fieldtype": "Int", - "label": "Inspection ID", - "read_only": 1 - }, - { - "fieldname": "vid", - "fieldtype": "Int", - "label": "Vehicle ID", - "read_only": 1 - }, - { - "fieldname": "noplate", - "fieldtype": "Data", - "label": "Vehicle Plate", - "in_list_view": 1, - "in_standard_filter": 1 - }, - { - "fieldname": "licence", - "fieldtype": "Data", - "label": "License Number" - }, - { - "fieldname": "vehicle_doc", - "fieldtype": "Link", - "label": "Vehicle", - "options": "Vehicle" - }, - { - "fieldname": "section_break_1", - "fieldtype": "Section Break", - "label": "Inspection Details" - }, - { - "fieldname": "inspection_date", - "fieldtype": "Date", - "label": "Inspection Date", - "in_list_view": 1 - }, - { - "fieldname": "valid_until", - "fieldtype": "Date", - "label": "Valid Until", - "in_list_view": 1 - }, - { - "fieldname": "final_result", - "fieldtype": "Select", - "label": "Final Result", - "options": "\nPass\nFail", - "in_list_view": 1, - "in_standard_filter": 1 - }, - { - "fieldname": "section_break_2", - "fieldtype": "Section Break", - "label": "Inspector Information" - }, - { - "fieldname": "inspector", - "fieldtype": "Data", - "label": "Inspector Name" - }, - { - "fieldname": "inspector_id", - "fieldtype": "Data", - "label": "Inspector ID" - }, - { - "fieldname": "email", - "fieldtype": "Data", - "label": "Inspector Email" - }, - { - "fieldname": "column_break_1", - "fieldtype": "Column Break" - }, - { - "fieldname": "region", - "fieldtype": "Data", - "label": "Region", - "in_standard_filter": 1 - }, - { - "fieldname": "district", - "fieldtype": "Data", - "label": "District", - "in_standard_filter": 1 - }, - { - "fieldname": "section_break_3", - "fieldtype": "Section Break", - "label": "Vehicle & Driver Information" - }, - { - "fieldname": "driver_name", - "fieldtype": "Data", - "label": "Driver Name" - }, - { - "fieldname": "driver_address", - "fieldtype": "Text", - "label": "Driver Address" - }, - { - "fieldname": "vehicle_passed_for", - "fieldtype": "Data", - "label": "Vehicle Passed For" - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "weight", - "fieldtype": "Data", - "label": "Weight Category" - }, - { - "fieldname": "prohibition_on_use", - "fieldtype": "Select", - "label": "Prohibition on Use", - "options": "\nYes\nNo" - }, - { - "fieldname": "originates", - "fieldtype": "Data", - "label": "Originates" - }, - { - "fieldname": "section_break_4", - "fieldtype": "Section Break", - "label": "Test Results - Part 1" - }, - { - "fieldname": "speed_test", - "fieldtype": "Select", - "label": "Speed Test", - "options": "\nPass\nFail" - }, - { - "fieldname": "electrical_system", - "fieldtype": "Select", - "label": "Electrical System", - "options": "\nPass\nFail" - }, - { - "fieldname": "fitting_equipment", - "fieldtype": "Select", - "label": "Fitting Equipment", - "options": "\nPass\nFail" - }, - { - "fieldname": "braking_system", - "fieldtype": "Select", - "label": "Braking System", - "options": "\nPass\nFail" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "wheels", - "fieldtype": "Select", - "label": "Wheels", - "options": "\nPass\nFail" - }, - { - "fieldname": "suspension", - "fieldtype": "Select", - "label": "Suspension", - "options": "\nPass\nFail" - }, - { - "fieldname": "steering", - "fieldtype": "Select", - "label": "Steering", - "options": "\nPass\nFail" - }, - { - "fieldname": "engine", - "fieldtype": "Select", - "label": "Engine", - "options": "\nPass\nFail" - }, - { - "fieldname": "section_break_5", - "fieldtype": "Section Break", - "label": "Test Results - Part 2" - }, - { - "fieldname": "exhaust", - "fieldtype": "Select", - "label": "Exhaust", - "options": "\nPass\nFail" - }, - { - "fieldname": "transmission", - "fieldtype": "Select", - "label": "Transmission", - "options": "\nPass\nFail" - }, - { - "fieldname": "instruments_panel", - "fieldtype": "Select", - "label": "Instruments Panel", - "options": "\nPass\nFail" - }, - { - "fieldname": "dimensions", - "fieldtype": "Select", - "label": "Dimensions", - "options": "\nPass\nFail" - }, - { - "fieldname": "radiation", - "fieldtype": "Select", - "label": "Radiation", - "options": "\nPass\nFail" - }, - { - "fieldname": "section_break_6", - "fieldtype": "Section Break", - "label": "Additional Information" - }, - { - "fieldname": "remarks", - "fieldtype": "Long Text", - "label": "Remarks" - }, - { - "fieldname": "created_at", - "fieldtype": "Datetime", - "label": "Created At", - "read_only": 1 - }, - { - "fieldname": "updated_at", - "fieldtype": "Datetime", - "label": "Updated At", - "read_only": 1 - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "links": [], - "modified": "2025-09-01 23:07:31.734846", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Vehicle Inspection Record", - "naming_rule": "By fieldname", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "row_format": "Dynamic", - "sort_field": "inspection_date", - "sort_order": "DESC", - "states": [], - "title_field": "noplate", - "track_changes": 1 -} diff --git a/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.py b/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.py deleted file mode 100644 index c5fdb9d1..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_inspection_record/vehicle_inspection_record.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class VehicleInspectionRecord(Document): - pass diff --git a/csf_tz/csf_tz/doctype/vehicle_location_log/__init__.py b/csf_tz/csf_tz/doctype/vehicle_location_log/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/vehicle_location_log/test_vehicle_location_log.py b/csf_tz/csf_tz/doctype/vehicle_location_log/test_vehicle_location_log.py deleted file mode 100644 index bb502f38..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_location_log/test_vehicle_location_log.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2024, Aakvatech and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestVehicleLocationLog(FrappeTestCase): - pass diff --git a/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.js b/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.js deleted file mode 100644 index 9e7cc2b1..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2024, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Vehicle Location Log', { - // refresh: function(frm) { - - // } -}); diff --git a/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.json b/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.json deleted file mode 100644 index 945d7a7a..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "autoname": "format:{vehicle}-{timestamp}", - "creation": "2024-05-27 11:04:45.996657", - "default_view": "List", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "type_of_update", - "vehicle", - "location", - "location_details", - "longitude", - "latitude", - "comment", - "column_break_adbpw", - "timestamp", - "map", - "amended_from" - ], - "fields": [ - { - "default": "Manual Update", - "fieldname": "type_of_update", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Type of Update", - "options": "Manual Update\nGPS Update", - "read_only": 1, - "reqd": 1 - }, - { - "fieldname": "location", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Location", - "reqd": 1 - }, - { - "fieldname": "longitude", - "fieldtype": "Data", - "label": "Longitude", - "read_only": 1 - }, - { - "fieldname": "latitude", - "fieldtype": "Data", - "label": "Latitude", - "read_only": 1 - }, - { - "fieldname": "comment", - "fieldtype": "Small Text", - "label": "Comment" - }, - { - "fieldname": "column_break_adbpw", - "fieldtype": "Column Break" - }, - { - "default": "Now", - "fieldname": "timestamp", - "fieldtype": "Datetime", - "in_list_view": 1, - "label": "Date", - "reqd": 1 - }, - { - "fieldname": "map", - "fieldtype": "Geolocation", - "label": "map", - "read_only": 1 - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Vehicle Location Log", - "print_hide": 1, - "read_only": 1, - "search_index": 1 - }, - { - "fieldname": "location_details", - "fieldtype": "Data", - "label": "Address", - "read_only": 1 - }, - { - "fieldname": "vehicle", - "fieldtype": "Link", - "label": "Vehicle", - "options": "Vehicle" - } - ], - "index_web_pages_for_search": 1, - "is_submittable": 1, - "links": [], - "modified": "2024-06-12 16:21:27.342865", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Vehicle Location Log", - "naming_rule": "Expression", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.py b/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.py deleted file mode 100644 index 2a8a5fd3..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_location_log/vehicle_location_log.py +++ /dev/null @@ -1,65 +0,0 @@ -import frappe -import requests -import json -from frappe.model.document import Document - -class VehicleLocationLog(Document): - def before_save(self): - if not self.location: - frappe.throw("Location name is required.") - - if not self.latitude and not self.longitude: - coordinates = self.fetch_coordinates(self.location) - - if not coordinates: - frappe.throw("Coordinates could not be fetched.") - - self.latitude = coordinates.get('latitude') - self.longitude = coordinates.get('longitude') - self.map = self.construct_map_field(coordinates) - self.location_details = coordinates.get('display_name') - - def fetch_coordinates(self, location_name): - url = "https://nominatim.openstreetmap.org/search" - params = { - 'format': 'json', - 'q': location_name - } - headers = { - 'User-Agent': 'MyApp/1.0 (youremail@example.com)' - } - try: - response = requests.get(url, params=params, headers=headers) - response.raise_for_status() - data = response.json() - - if not data: - return None - - # Select the first entry from the results - location = max(data, key=lambda x: x.get('importance', 0)) - return { - 'latitude': location.get('lat'), - 'longitude': location.get('lon'), - 'display_name': location.get('display_name') - } - except requests.exceptions.RequestException as e: - frappe.throw(f"Error fetching coordinates: {str(e)}") - - def construct_map_field(self, coordinates): - map_data = { - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [float(coordinates['longitude']), float(coordinates['latitude'])] - }, - "properties": { - "icon": "vehicle" - } - } - ] - } - return json.dumps(map_data) diff --git a/csf_tz/csf_tz/doctype/vehicle_sync_task/__init__.py b/csf_tz/csf_tz/doctype/vehicle_sync_task/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/vehicle_sync_task/processor.py b/csf_tz/csf_tz/doctype/vehicle_sync_task/processor.py deleted file mode 100644 index 18a837d4..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_sync_task/processor.py +++ /dev/null @@ -1,768 +0,0 @@ -import requests -from datetime import datetime -from time import sleep -import frappe -from frappe.utils import cint, get_datetime - -# Safe import with fallback -try: - import csf_tz.csf_tz.doctype.vehicle_sync_task.queue as queue -except (ImportError, AttributeError) as e: - frappe.log_error("Queue Import Warning", str(e)) - queue = None - -# ------------ CONFIGURATION ------------ -HOST = "https://tms.tpf.go.tz/api/OffenceCheck" -TASK_DOCTYPE = "Vehicle Sync Task" -SYNC_LAST_RUN_CACHE_KEY = "csf_tz:vehicle_sync:last_batch_run_at" - - -def _get_sync_settings(): - settings = frappe.get_cached_doc("CSF TZ Settings") - enable_sync = cint(settings.get("enable_sync")) - batch_size = cint(settings.get("batch_size")) - sync_interval = cint(settings.get("sync_interval")) - - if batch_size < 1: - batch_size = 1 - if sync_interval < 1: - sync_interval = 1 - - return { - "enable_sync": enable_sync, - "batch_size": batch_size, - "sync_interval": sync_interval, - } - - -def _is_batch_due(sync_interval): - cache = frappe.cache() - last_run_at = cache.get_value(SYNC_LAST_RUN_CACHE_KEY) - if not last_run_at: - return True - - try: - last_run = get_datetime(last_run_at) - except Exception: - return True - - next_allowed_run = frappe.utils.add_to_date(last_run, minutes=sync_interval) - return frappe.utils.now_datetime() >= next_allowed_run - - -def _mark_batch_run(): - frappe.cache().set_value(SYNC_LAST_RUN_CACHE_KEY, frappe.utils.now()) - - -def _schedule_task_by_interval(task_name, sync_interval): - now = frappe.utils.now_datetime() - active_task_count = ( - frappe.db.sql( - f"select count(name) from `tab{TASK_DOCTYPE}` where ifnull(is_deleted, 0) = 0" - )[0][0] - or 1 - ) - next_run = frappe.utils.add_to_date(now, minutes=(sync_interval * active_task_count)) - frappe.db.set_value( - TASK_DOCTYPE, - task_name, - { - "status": "Success", - "last_run_at": now, - "next_run_at": next_run, - "claimed_by": "", - "claimed_at": None, - "last_error": "", - "attempts": 0, - "backoff_exp": 0, - }, - ) - return next_run - -# ------------ FALLBACK QUEUE FUNCTIONS ------------ -def _reset_stuck_tasks_fallback(doctype, timeout_minutes=10): - """Fallback implementation when queue module fails""" - try: - timeout_time = frappe.utils.add_to_date(frappe.utils.now_datetime(), minutes=-timeout_minutes) - Task = frappe.qb.DocType(doctype) - - stuck = ( - frappe.qb.from_(Task) - .select(Task.name) - .where( - (Task.status == "Processing") & - (Task.claimed_at < timeout_time) & - ((Task.is_deleted.isnull()) | (Task.is_deleted == 0)) - ) - ).run(as_dict=True) - - for row in stuck: - frappe.db.set_value(doctype, row["name"], { - "status": "Pending", - "claimed_by": "", - "claimed_at": None, - "next_run_at": frappe.utils.now_datetime() - }) - return len(stuck) - except Exception as e: - frappe.log_error("Reset Stuck Tasks Fallback Failed", str(e)) - return 0 - -def _claim_batch_fallback(doctype, limit=5): - """Fallback claim batch when queue module fails""" - try: - now = frappe.utils.now_datetime() - worker_id = frappe.local.site - Task = frappe.qb.DocType(doctype) - - rows = ( - frappe.qb.from_(Task) - .select(Task.name) - .where( - (Task.status.isin(["Pending", "Success"])) & - ((Task.next_run_at.isnull()) | (Task.next_run_at <= now)) & - ((Task.is_deleted.isnull()) | (Task.is_deleted == 0)) - ) - .orderby(Task.priority, order=frappe.qb.terms.Order.desc) - .orderby(Task.name) - .limit(limit) - ).run(as_dict=True) - - if not rows: - return [] - - claimed = [] - for row in rows: - frappe.db.set_value(doctype, row["name"], { - "status": "Processing", - "claimed_by": worker_id, - "claimed_at": now, - "last_run_at": now, - }) - data = frappe.db.get_value(doctype, row["name"], ["name", "vehicle_no"], as_dict=True) - claimed.append(data) - return claimed - except Exception as e: - frappe.log_error("Claim Batch Fallback Failed", str(e)) - return [] - -def _mark_done_fallback(doctype, task): - """Fallback mark done when queue module fails""" - try: - frappe.db.set_value(doctype, task["name"], { - "status": "Success", - "last_run_at": frappe.utils.now_datetime(), - "claimed_by": "", - "claimed_at": None, - "next_run_at": None, - "last_error": "" - }) - except Exception as e: - frappe.log_error("Mark Done Fallback Failed", str(e)) - -# ------------ API INTEGRATION ------------ -def _call_external_api(vehicle_no): - if not vehicle_no or len(vehicle_no) < 7: - raise Exception(f"Invalid vehicle license plate: {vehicle_no}") - - payload = {"vehicle": vehicle_no} - headers = {"Content-Type": "application/json", "Accept": "application/json"} - try: - sleep(2) - response = requests.post(HOST, json=payload, headers=headers, timeout=10) - response.raise_for_status() - result = response.json() - except Exception as e: - raise Exception(f"API/Parse error for {vehicle_no}: {str(e)}") - - # Process Fine Records - fine_records_created, fine_records_updated = _process_fine_records(vehicle_no, result) - - # Process Inspection Records - inspection_records_created, inspection_records_updated = _process_inspection_records(vehicle_no, result) - - return { - "status": "success", - "vehicle": vehicle_no, - "pending_fines": len(result.get("pending_transactions", [])), - "fine_records_created": fine_records_created, - "fine_records_updated": fine_records_updated, - "inspection_records_created": inspection_records_created, - "inspection_records_updated": inspection_records_updated, - "total_pending_amount": result.get("totalPendingAmount", "0.00"), - "has_inspection_data": bool(result.get("inspection_data")) - } - -def _process_fine_records(vehicle_no, result): - """Process pending transactions into Vehicle Fine Records""" - pending_transactions = result.get("pending_transactions", []) - fine_records_created = 0 - fine_records_updated = 0 - - if pending_transactions: - for tx in pending_transactions: - ref = tx.get("reference", "") - if not ref: - continue - - # Check if record exists by reference (unique field) - existing_record = frappe.db.get_value("Vehicle Fine Record", - {"reference": ref}, - ["name", "charge", "penalty", "total", "status"]) - - if not existing_record: - # CREATE NEW RECORD - try: - rec = frappe.new_doc("Vehicle Fine Record") - - # Proper field mapping from API to DocType - rec.reference = ref # reference - rec.issued_date = tx.get("issued_date", "") # issued_date - rec.officer = tx.get("operator", "") # operator -> officer - rec.vehicle = tx.get("vehicle", vehicle_no) # vehicle - rec.licence = tx.get("licence", "") # licence - rec.location = tx.get("location", "") # location - rec.offence = tx.get("offence", "") # offence - rec.status = tx.get("status", "PENDING") # status - - # Currency fields - convert string to float - charge = float(tx.get("charge", 0)) if tx.get("charge") else 0 - penalty = float(tx.get("penalty", 0)) if tx.get("penalty") else 0 - - rec.charge = charge # charge - rec.penalty = penalty # penalty - rec.total = charge + penalty # total (calculated) - - # Link to Vehicle document if exists - vehicle_doc = frappe.db.get_value("Vehicle", - {"license_plate": vehicle_no}, - "name") - if vehicle_doc: - rec.vehicle_doc = vehicle_doc # vehicle_doc - - rec.insert(ignore_permissions=True) - fine_records_created += 1 - - except Exception as e: - frappe.log_error( - title="Vehicle Fine Record Creation Failed", - message=f"Error creating fine record for vehicle {vehicle_no}, reference {ref}: {str(e)}" - ) - else: - # UPDATE EXISTING RECORD - try: - record_name = existing_record[0] if isinstance(existing_record, tuple) else existing_record - - # Get current values - current_charge = existing_record[1] if isinstance(existing_record, tuple) else frappe.db.get_value("Vehicle Fine Record", record_name, "charge") - current_penalty = existing_record[2] if isinstance(existing_record, tuple) else frappe.db.get_value("Vehicle Fine Record", record_name, "penalty") - current_status = existing_record[4] if isinstance(existing_record, tuple) else frappe.db.get_value("Vehicle Fine Record", record_name, "status") - - # New values from API - new_charge = float(tx.get("charge", 0)) if tx.get("charge") else 0 - new_penalty = float(tx.get("penalty", 0)) if tx.get("penalty") else 0 - new_status = tx.get("status", "PENDING") - new_total = new_charge + new_penalty - - # Check if any field needs update - update_needed = False - update_data = {} - - if current_charge != new_charge: - update_data["charge"] = new_charge - update_needed = True - - if current_penalty != new_penalty: - update_data["penalty"] = new_penalty - update_needed = True - - if current_status != new_status: - update_data["status"] = new_status - update_needed = True - - # Always update total if charge/penalty changed - if "charge" in update_data or "penalty" in update_data: - update_data["total"] = new_total - update_needed = True - - # Update other fields that might change - update_data["issued_date"] = tx.get("issued_date", "") - update_data["officer"] = tx.get("operator", "") - update_data["location"] = tx.get("location", "") - update_data["offence"] = tx.get("offence", "") - - if update_needed or any(update_data.values()): - # Perform bulk update - frappe.db.set_value("Vehicle Fine Record", record_name, update_data) - fine_records_updated += 1 - - frappe.logger().info(f"Updated fine record {ref} - Charge: {current_charge}→{new_charge}, Penalty: {current_penalty}→{new_penalty}, Status: {current_status}→{new_status}") - - except Exception as e: - frappe.log_error( - title="Vehicle Fine Record Update Failed", - message=f"Error updating fine record {ref} for vehicle {vehicle_no}: {str(e)}" - ) - else: - # No pending transactions - mark existing unpaid records as PAID - try: - existing = frappe.get_all("Vehicle Fine Record", - filters={"vehicle": vehicle_no, "status": ["!=", "PAID"]}, - pluck="name") - for record in existing: - frappe.db.set_value("Vehicle Fine Record", record, "status", "PAID") - fine_records_updated += 1 - except Exception as e: - frappe.log_error( - title="Vehicle Fine Record Update Failed", - message=f"Error updating fine records to PAID for vehicle {vehicle_no}: {str(e)}" - ) - - return fine_records_created, fine_records_updated - -def _process_inspection_records(vehicle_no, result): - """Process inspection data into Vehicle Inspection Records""" - inspection_data = result.get("inspection_data", []) - inspection_records_created = 0 - inspection_records_updated = 0 - - if inspection_data: - for inspection in inspection_data: - vir_no = inspection.get("vir_no", "") - if not vir_no: - continue - - # Check if record exists by VIR number (unique field) - existing_record = frappe.db.get_value("Vehicle Inspection Record", - {"vir_no": vir_no}, - ["name", "updated_at"]) - - if not existing_record: - # CREATE NEW INSPECTION RECORD - try: - rec = frappe.new_doc("Vehicle Inspection Record") - - # Basic Information - rec.vir_no = vir_no # VIR Number - rec.inspection_id = inspection.get("id") # Inspection ID - rec.vid = inspection.get("vid") # Vehicle ID - rec.noplate = inspection.get("noplate", vehicle_no) # Vehicle Plate - rec.licence = inspection.get("licence", "") # License Number - rec.inspection_date = inspection.get("inspection_date") # Inspection Date - rec.valid_until = inspection.get("valid_untill") # Valid Until (API typo) - rec.final_result = inspection.get("finalresult") # Final Result - - # Inspector Information - rec.inspector = inspection.get("inspector", "") # Inspector Name - rec.inspector_id = inspection.get("inspector_id", "") # Inspector ID - rec.email = inspection.get("email", "") # Inspector Email - rec.region = inspection.get("region", "") # Region - rec.district = inspection.get("district", "") # District - - # Vehicle & Driver Information - rec.driver_name = inspection.get("driver_name", "") # Driver Name - rec.driver_address = inspection.get("driver_address", "") # Driver Address - rec.vehicle_passed_for = inspection.get("vehicle_passed_for", "") # Vehicle Type - rec.weight = inspection.get("weight", "") # Weight Category - rec.prohibition_on_use = inspection.get("prohibition_on_use", "") # Prohibition - rec.originates = inspection.get("originates", "") # Originates - - # Test Results (Pass/Fail) - rec.speed_test = inspection.get("speed_test", "") # Speed Test - rec.electrical_system = inspection.get("electrical_system", "") # Electrical - rec.fitting_equipment = inspection.get("fitting_equipment", "") # Fitting Equipment - rec.braking_system = inspection.get("braking_system", "") # Braking - rec.wheels = inspection.get("wheels", "") # Wheels - rec.suspension = inspection.get("suspension", "") # Suspension - rec.steering = inspection.get("steering", "") # Steering - rec.engine = inspection.get("engine", "") # Engine - rec.exhaust = inspection.get("exhaust", "") # Exhaust - rec.transmission = inspection.get("transimission", "") # Transmission (API typo) - rec.instruments_panel = inspection.get("instruments_panel", "") # Instruments - rec.dimensions = inspection.get("dimensions", "") # Dimensions - rec.radiation = inspection.get("radiation", "") # Radiation - - # Additional Information - rec.remarks = inspection.get("remarks", "") # Remarks - rec.created_at = inspection.get("created_at", "") # Created At - rec.updated_at = inspection.get("updated_at", "") # Updated At - - # Link to Vehicle document if exists - vehicle_doc = frappe.db.get_value("Vehicle", - {"license_plate": vehicle_no}, - "name") - if vehicle_doc: - rec.vehicle_doc = vehicle_doc - - rec.insert(ignore_permissions=True) - inspection_records_created += 1 - - frappe.logger().info(f"Created inspection record {vir_no} for vehicle {vehicle_no}") - - except Exception as e: - frappe.log_error( - title="Vehicle Inspection Record Creation Failed", - message=f"Error creating inspection record for vehicle {vehicle_no}, VIR: {vir_no}: {str(e)}" - ) - else: - # UPDATE EXISTING INSPECTION RECORD - try: - record_name = existing_record[0] if isinstance(existing_record, tuple) else existing_record - api_updated_at = inspection.get("updated_at", "") - current_updated_at = existing_record[1] if isinstance(existing_record, tuple) else frappe.db.get_value("Vehicle Inspection Record", record_name, "updated_at") - - # Only update if API data is newer - if api_updated_at and (not current_updated_at or api_updated_at > str(current_updated_at)): - - update_data = { - "inspection_date": inspection.get("inspection_date"), - "valid_until": inspection.get("valid_untill"), - "final_result": inspection.get("finalresult"), - "inspector": inspection.get("inspector", ""), - "inspector_id": inspection.get("inspector_id", ""), - "email": inspection.get("email", ""), - "region": inspection.get("region", ""), - "district": inspection.get("district", ""), - "driver_name": inspection.get("driver_name", ""), - "driver_address": inspection.get("driver_address", ""), - "vehicle_passed_for": inspection.get("vehicle_passed_for", ""), - "weight": inspection.get("weight", ""), - "prohibition_on_use": inspection.get("prohibition_on_use", ""), - "originates": inspection.get("originates", ""), - "speed_test": inspection.get("speed_test", ""), - "electrical_system": inspection.get("electrical_system", ""), - "fitting_equipment": inspection.get("fitting_equipment", ""), - "braking_system": inspection.get("braking_system", ""), - "wheels": inspection.get("wheels", ""), - "suspension": inspection.get("suspension", ""), - "steering": inspection.get("steering", ""), - "engine": inspection.get("engine", ""), - "exhaust": inspection.get("exhaust", ""), - "transmission": inspection.get("transimission", ""), # API typo - "instruments_panel": inspection.get("instruments_panel", ""), - "dimensions": inspection.get("dimensions", ""), - "radiation": inspection.get("radiation", ""), - "remarks": inspection.get("remarks", ""), - "updated_at": api_updated_at - } - - frappe.db.set_value("Vehicle Inspection Record", record_name, update_data) - inspection_records_updated += 1 - - frappe.logger().info(f"Updated inspection record {vir_no} for vehicle {vehicle_no}") - - except Exception as e: - frappe.log_error( - title="Vehicle Inspection Record Update Failed", - message=f"Error updating inspection record {vir_no} for vehicle {vehicle_no}: {str(e)}" - ) - - return inspection_records_created, inspection_records_updated - -# ------------ MAIN PROCESSOR ------------ -@frappe.whitelist() -def run_vehicle_batch(): - start = datetime.utcnow() - processed, errors = 0, 0 - - try: - print(f"[Vehicle Sync] run_vehicle_batch triggered at {frappe.utils.now()}") - sync_settings = _get_sync_settings() - if not sync_settings["enable_sync"]: - print("[Vehicle Sync] skipped: sync disabled in settings") - return {"status": "disabled", "message": "Vehicle sync is disabled in CSF TZ Settings"} - - if not _is_batch_due(sync_settings["sync_interval"]): - print(f"[Vehicle Sync] skipped: waiting for interval ({sync_settings['sync_interval']} minute(s))") - return { - "status": "skipped", - "message": f"Waiting for sync interval ({sync_settings['sync_interval']} minute(s))", - } - - # Reset stuck tasks - use queue module or fallback - if queue and hasattr(queue, 'reset_stuck_tasks'): - queue.reset_stuck_tasks(TASK_DOCTYPE, timeout_minutes=10) - else: - _reset_stuck_tasks_fallback(TASK_DOCTYPE, timeout_minutes=10) - - # Claim batch of tasks - if queue and hasattr(queue, 'claim_batch'): - tasks = queue.claim_batch(TASK_DOCTYPE, limit=sync_settings["batch_size"]) - else: - tasks = _claim_batch_fallback(TASK_DOCTYPE, limit=sync_settings["batch_size"]) - - if not tasks: - print("[Vehicle Sync] no tasks to process") - return {"status": "no_tasks", "message": f"No pending tasks at {start}"} - - _mark_batch_run() - print(f"[Vehicle Sync] processing {len(tasks)} task(s)") - - for task in tasks: - try: - _call_external_api(task["vehicle_no"]) - - # Schedule next processing by configured sync interval - _schedule_task_by_interval(task["name"], sync_settings["sync_interval"]) - processed += 1 - except Exception as e: - errors += 1 - error_msg = str(e) - frappe.log_error( - title="Vehicle API Processing Failed", - message=f"Error processing vehicle {task.get('vehicle_no')}: {error_msg}" - ) - - # Handle failed task - use queue or simple fallback - if queue and hasattr(queue, 'bump_attempts'): - current_attempts = frappe.db.get_value(TASK_DOCTYPE, task["name"], "attempts") or 0 - backoff_seconds = getattr(queue, 'BASE_BACKOFF', 300) * (2 ** (current_attempts + 1)) - queue.schedule_next(TASK_DOCTYPE, task, backoff_seconds, error_msg) - else: - # Simple fallback - mark as pending for retry - frappe.db.set_value(TASK_DOCTYPE, task["name"], { - "status": "Pending", - "last_error": error_msg[:500], - "next_run_at": frappe.utils.add_to_date(frappe.utils.now_datetime(), minutes=5) - }) - - # Check time budget - time_budget = getattr(queue, 'TIME_BUDGET_SEC', 50) if queue else 50 - if (datetime.utcnow() - start).total_seconds() > time_budget: - break - - frappe.db.commit() - total_runtime = (datetime.utcnow() - start).total_seconds() - print(f"[Vehicle Sync] completed: processed={processed}, errors={errors}, runtime={total_runtime:.2f}s") - return { - "status": "completed", - "runtime_seconds": total_runtime, - "processed": processed, - "errors": errors, - "total_claimed": len(tasks) - } - except Exception as e: - frappe.log_error( - title="Vehicle Batch Processing Failed", - message=f"Critical error in run_vehicle_batch: {str(e)}" - ) - return {"status": "error", "message": str(e)} - -# ------------ 15-MINUTE CYCLE MANAGEMENT ------------ -@frappe.whitelist() -def reset_cycle(): - try: - Task = frappe.qb.DocType(TASK_DOCTYPE) - - done_tasks = ( - frappe.qb.from_(Task) - .select(Task.name) - .where(Task.status == "Done") - ).run(as_dict=True) - - completed_reset = 0 - for row in done_tasks: - try: - frappe.db.set_value(TASK_DOCTYPE, row["name"], { - "status": "Pending", - "next_run_at": frappe.utils.now(), - "claimed_by": "", - "claimed_at": None, - "last_error": "" - }) - completed_reset += 1 - except Exception as e: - frappe.log_error( - title="Task Reset Failed", - message=f"Error resetting completed task {row['name']}: {str(e)}" - ) - - from frappe.utils import add_to_date, now_datetime - failed_tasks = ( - frappe.qb.from_(Task) - .select(Task.name) - .where((Task.status == "Failed") & - (Task.last_run_at < add_to_date(now_datetime(), hours=-1))) - ).run(as_dict=True) - - failed_reset = 0 - for row in failed_tasks: - try: - frappe.db.set_value(TASK_DOCTYPE, row["name"], { - "status": "Pending", - "next_run_at": frappe.utils.now(), - "attempts": 0, - "backoff_exp": 0, - "claimed_by": "", - "claimed_at": None, - }) - failed_reset += 1 - except Exception as e: - frappe.log_error( - title="Failed Task Reset Error", - message=f"Error resetting failed task {row['name']}: {str(e)}" - ) - - frappe.db.commit() - return { - "cycle_reset": True, - "completed_reset": completed_reset, - "failed_reset": failed_reset, - "total_reset": completed_reset + failed_reset, - } - except Exception as e: - frappe.log_error( - title="Cycle Reset Failed", - message=f"Critical error in reset_cycle: {str(e)}" - ) - return {"status": "error", "message": str(e)} - -@frappe.whitelist() -def create_sync_task(vehicle_no, priority=0, immediate=False): - try: - # Check for existing active tasks (not deleted) - existing = frappe.db.get_value( - TASK_DOCTYPE, - { - "vehicle_no": vehicle_no, - "status": ["in", ["Pending", "Processing", "Success"]], - "is_deleted": ["!=", 1] # Only check non-deleted tasks - }, - "name" - ) - - if existing: - if immediate or priority > 5: - frappe.db.set_value(TASK_DOCTYPE, existing, { - "priority": max(priority, 5), - "next_run_at": frappe.utils.now_datetime() - }) - return existing - - # Check if deleted task exists - reactivate it instead of creating new - deleted_task = frappe.db.get_value( - TASK_DOCTYPE, - {"vehicle_no": vehicle_no, "is_deleted": 1}, - "name" - ) - - if deleted_task: - # Reactivate deleted task - frappe.db.set_value(TASK_DOCTYPE, deleted_task, { - "is_deleted": 0, - "status": "Pending", - "priority": priority, - "attempts": 0, - "backoff_exp": 0, - "next_run_at": frappe.utils.now_datetime() if immediate else None, - "claimed_by": "", - "claimed_at": None, - "last_error": "" - }) - return deleted_task - - # Create new task - task = frappe.new_doc(TASK_DOCTYPE) - task.vehicle_no = vehicle_no - task.status = "Pending" - task.priority = priority - task.attempts = 0 - task.backoff_exp = 0 - task.is_deleted = 0 # Explicitly set to 0 - task.next_run_at = frappe.utils.now_datetime() if immediate else None - task.insert(ignore_permissions=True) - return task.name - - except Exception as e: - frappe.log_error( - title="Sync Task Creation Failed", - message=f"Error creating sync task for vehicle {vehicle_no}: {str(e)}" - ) - return None -@frappe.whitelist() -def seed_vehicle_sync_queue(): - """ - Updated: Handles new vehicles, existing vehicles, and marks deleted ones. - Can be used for initial seeding AND daily sync. - """ - try: - # Current vehicles from Vehicle doctype - current_vehicles = frappe.get_all( - "Vehicle", - fields=["license_plate", "name"], - filters={"license_plate": ["is", "set"]} - ) - - - # All existing sync tasks (including deleted ones) - all_tasks = frappe.get_all( - TASK_DOCTYPE, - fields=["vehicle_no", "name", "is_deleted"] - ) - - - current_plates = { - vehicle.license_plate or vehicle.name - for vehicle in current_vehicles if (vehicle.license_plate or vehicle.name) - } - existing_tasks_map = {task.vehicle_no: task for task in all_tasks} - active_plates = {task.vehicle_no for task in all_tasks if not task.is_deleted} - - - created = skipped = invalid = reactivated = deleted_marked = 0 - - - # Process current vehicles - for vehicle in current_vehicles: - try: - number_plate = vehicle.license_plate or vehicle.name - if number_plate: - if number_plate not in existing_tasks_map: - # New vehicle - create sync task - create_sync_task(number_plate, priority=0) - created += 1 - elif existing_tasks_map[number_plate].is_deleted: - # Previously deleted vehicle is back - reactivate using create_sync_task - create_sync_task(number_plate, priority=0) - reactivated += 1 - else: - # Already exists and active - skipped += 1 - else: - invalid += 1 - except Exception as e: - frappe.log_error( - title="Vehicle Sync Queue Seed Error", - message=f"Error processing vehicle {vehicle.get('license_plate') or vehicle.get('name')}: {str(e)}" - ) - - - # Mark vehicles as deleted if they don't exist in current Vehicle doctype - for plate in active_plates: - if plate not in current_plates: - task_name = existing_tasks_map[plate].name - frappe.db.set_value(TASK_DOCTYPE, task_name, "is_deleted", 1) - deleted_marked += 1 - - - frappe.db.commit() - - - return { - "status": "success", - "created": created, - "skipped": skipped, - "invalid": invalid, - "reactivated": reactivated, - "deleted_marked": deleted_marked, - "total_vehicles": len(current_vehicles), - "total_valid_plates": len(current_plates) - } - - - except Exception as e: - frappe.log_error( - title="Seed Vehicle Sync Queue Failed", - message=f"Critical error in seed_vehicle_sync_queue: {str(e)}" - ) - return {"status": "error", "message": str(e)} diff --git a/csf_tz/csf_tz/doctype/vehicle_sync_task/queue.py b/csf_tz/csf_tz/doctype/vehicle_sync_task/queue.py deleted file mode 100644 index f99e3db7..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_sync_task/queue.py +++ /dev/null @@ -1,162 +0,0 @@ -import secrets -import frappe - -# ------------ CONFIGURATION ------------ -BATCH_SIZE = 5 -TIME_BUDGET_SEC = 50 -MAX_ATTEMPTS = 8 -BASE_BACKOFF = 300 -BACKOFF_JITTER = 0.2 -WORKER_ID = frappe.local.site - -# ------------ INTERNAL HELPERS ------------ -def _now(): - return frappe.utils.now_datetime() - -def _jitter(seconds): - # Generate cryptographically secure random jitter for backoff timing - # Range: -BACKOFF_JITTER to +BACKOFF_JITTER - random_factor = (secrets.randbelow(10000) / 10000.0) * 2 - 1 # -1 to 1 - jitter_factor = 1 + (random_factor * BACKOFF_JITTER) - return int(seconds * jitter_factor) - -# ------------ CORE QUEUE OPERATIONS ------------ -def claim_batch(doctype, limit=BATCH_SIZE): - try: - now = _now() - Task = frappe.qb.DocType(doctype) - - rows = ( - frappe.qb.from_(Task) - .select(Task.name) - .where( - (Task.status.isin(["Pending", "Success"])) & - ((Task.next_run_at.isnull()) | (Task.next_run_at <= now)) & - ((Task.is_deleted.isnull()) | (Task.is_deleted == 0)) # ← IGNORE DELETED TASKS - ) - .orderby(Task.priority, order=frappe.qb.terms.Order.desc) - .orderby(Task.name) - .limit(limit) - ).run(as_dict=True) - - if not rows: - return [] - - claimed = [] - for row in rows: - frappe.db.set_value(doctype, row["name"], { - "status": "Processing", - "claimed_by": WORKER_ID, - "claimed_at": now, - "last_run_at": now, - }) - data = frappe.db.get_value(doctype, row["name"], ["name", "vehicle_no"], as_dict=True) - claimed.append(data) - return claimed - except Exception as e: - frappe.log_error( - title="Queue Claim Batch Failed", - message=f"Error claiming batch from {doctype}: {str(e)}" - ) - return [] - -def mark_done(doctype, task): - try: - frappe.db.set_value(doctype, task["name"], { - "status": "Success", - "last_run_at": _now(), - "claimed_by": "", - "claimed_at": None, - "next_run_at": None, - "last_error": "" - }) - except Exception as e: - frappe.log_error( - title="Queue Mark Done Failed", - message=f"Error marking task {task.get('name')} as done in {doctype}: {str(e)}" - ) - -def mark_failed(doctype, task, err_msg): - try: - frappe.db.set_value(doctype, task["name"], { - "status": "Failed", - "last_error": err_msg[:1000], - "last_run_at": _now(), - "claimed_by": "", - "claimed_at": None, - "next_run_at": None, - }) - except Exception as e: - frappe.log_error( - title="Queue Mark Failed Error", - message=f"Error marking task {task.get('name')} as failed in {doctype}: {str(e)}" - ) - -def bump_attempts(doctype, task): - try: - current = frappe.db.get_value( - doctype, task["name"], ["attempts", "backoff_exp"], as_dict=True - ) - attempts = (current.attempts or 0) + 1 - backoff_exp = min((current.backoff_exp or 0) + 1, 6) - frappe.db.set_value(doctype, task["name"], { - "attempts": attempts, - "backoff_exp": backoff_exp, - "last_run_at": _now() - }) - return attempts, backoff_exp - except Exception as e: - frappe.log_error( - title="Queue Bump Attempts Failed", - message=f"Error bumping attempts for task {task.get('name')} in {doctype}: {str(e)}" - ) - return 1, 1 # Return default values - -def schedule_next(doctype, task, backoff_seconds, error_msg=""): - try: - attempts, _ = bump_attempts(doctype, task) - if attempts >= MAX_ATTEMPTS: - mark_failed(doctype, task, error_msg or "Max attempts exceeded") - return - next_run = frappe.utils.add_to_date(_now(), seconds=_jitter(backoff_seconds)) - frappe.db.set_value(doctype, task["name"], { - "status": "Pending", - "claimed_by": "", - "claimed_at": None, - "next_run_at": next_run, - "last_error": error_msg[:500] if error_msg else "", - }) - except Exception as e: - frappe.log_error( - title="Queue Schedule Next Failed", - message=f"Error scheduling next run for task {task.get('name')} in {doctype}: {str(e)}" - ) - -def reset_stuck_tasks(doctype, timeout_minutes=10): - try: - timeout_time = frappe.utils.add_to_date(_now(), minutes=-timeout_minutes) - Task = frappe.qb.DocType(doctype) - stuck = ( - frappe.qb.from_(Task) - .select(Task.name) - .where( - (Task.status == "Processing") & - (Task.claimed_at < timeout_time) & - ((Task.is_deleted.isnull()) | (Task.is_deleted == 0)) # ← IGNORE DELETED TASKS - ) - ).run(as_dict=True) - - for row in stuck: - frappe.db.set_value(doctype, row["name"], { - "status": "Pending", - "claimed_by": "", - "claimed_at": None, - "next_run_at": _now() - }) - return len(stuck) - except Exception as e: - frappe.log_error( - title="Queue Reset Stuck Tasks Failed", - message=f"Error resetting stuck tasks in {doctype}: {str(e)}" - ) - return 0 diff --git a/csf_tz/csf_tz/doctype/vehicle_sync_task/test_vehicle_sync_task.py b/csf_tz/csf_tz/doctype/vehicle_sync_task/test_vehicle_sync_task.py deleted file mode 100644 index 09069b1e..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_sync_task/test_vehicle_sync_task.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestVehicleSyncTask(FrappeTestCase): - pass diff --git a/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.js b/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.js deleted file mode 100644 index 5799be16..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2025, Aakvatech and contributors -// For license information, please see license.txt - -// frappe.ui.form.on("Vehicle Sync Task", { -// refresh(frm) { - -// }, -// }); diff --git a/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.json b/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.json deleted file mode 100644 index 02bae021..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "actions": [], - "autoname": "autoincrement", - "creation": "2025-08-22 18:55:40.875910", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "vehicle_details_section", - "vehicle_no", - "column_break_nipc", - "priority", - "status_details_section", - "status", - "attempts", - "backoff_exp", - "column_break_btfh", - "next_run_at", - "last_run_at", - "execution_details_section", - "claimed_at", - "column_break_qlib", - "claimed_by", - "error_details_section", - "last_error", - "is_deleted" - ], - "fields": [ - { - "fieldname": "vehicle_no", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Vehicle No", - "no_copy": 1, - "unique": 1 - }, - { - "fieldname": "status", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Status", - "options": "\nPending\nProcessing\nSuccess\nFailed\nPaused", - "search_index": 1 - }, - { - "default": "0", - "fieldname": "attempts", - "fieldtype": "Int", - "label": "Attempts" - }, - { - "fieldname": "last_error", - "fieldtype": "Small Text", - "label": "Last Error" - }, - { - "fieldname": "vehicle_details_section", - "fieldtype": "Section Break", - "label": "Vehicle Details" - }, - { - "fieldname": "status_details_section", - "fieldtype": "Section Break", - "label": "Status Details" - }, - { - "fieldname": "next_run_at", - "fieldtype": "Datetime", - "in_list_view": 1, - "label": "Next Run at", - "search_index": 1 - }, - { - "default": "0", - "fieldname": "priority", - "fieldtype": "Int", - "label": "Priority", - "search_index": 1 - }, - { - "fieldname": "column_break_btfh", - "fieldtype": "Column Break" - }, - { - "default": "0", - "fieldname": "backoff_exp", - "fieldtype": "Int", - "label": "Backoff Exponent" - }, - { - "fieldname": "last_run_at", - "fieldtype": "Datetime", - "label": "Last Run at", - "search_index": 1 - }, - { - "fieldname": "claimed_by", - "fieldtype": "Data", - "label": "Claimed By" - }, - { - "fieldname": "claimed_at", - "fieldtype": "Datetime", - "label": "Claimed at" - }, - { - "fieldname": "column_break_nipc", - "fieldtype": "Column Break" - }, - { - "fieldname": "execution_details_section", - "fieldtype": "Section Break", - "label": "Execution Details" - }, - { - "fieldname": "column_break_qlib", - "fieldtype": "Column Break" - }, - { - "fieldname": "error_details_section", - "fieldtype": "Section Break", - "label": "Error Details" - }, - { - "default": "0", - "fieldname": "is_deleted", - "fieldtype": "Check", - "label": "is Deleted ?" - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "links": [], - "modified": "2025-09-14 21:43:07.623030", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Vehicle Sync Task", - "naming_rule": "Autoincrement", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [ - { - "color": "Yellow", - "title": "Pending" - }, - { - "color": "Blue", - "title": "Processing" - }, - { - "color": "Green", - "title": "Success" - }, - { - "color": "Red", - "title": "Failed" - }, - { - "color": "Gray", - "title": "Paused" - } - ] -} diff --git a/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.py b/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.py deleted file mode 100644 index 1d495f70..00000000 --- a/csf_tz/csf_tz/doctype/vehicle_sync_task/vehicle_sync_task.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -import frappe -from frappe.model.document import Document -from frappe.query_builder import Interval -from frappe.query_builder.functions import Now - -class VehicleSyncTask(Document): - @staticmethod - def clear_old_logs(days=7): - table = frappe.qb.DocType("Vehicle Sync Task") - frappe.db.delete(table, filters=(table.creation < (Now() - Interval(days=days)))) \ No newline at end of file diff --git a/csf_tz/hooks.py b/csf_tz/hooks.py index 4094d3bb..3529ffef 100755 --- a/csf_tz/hooks.py +++ b/csf_tz/hooks.py @@ -295,9 +295,6 @@ # "csf_tz.tasks.all" # ], "cron": { - "* * * * *": [ - "csf_tz.csf_tz.doctype.vehicle_sync_task.processor.run_vehicle_batch" - ], "0 */6 * * *": [ "csf_tz.csf_tz.doctype.parking_bill.parking_bill.check_bills_all_vehicles", ], @@ -305,7 +302,6 @@ "csf_tz.csf_tz.doctype.vehicle_fine_record.vehicle_fine_record.check_fine_all_vehicles", ], "*/15 * * * *": [ - "csf_tz.csf_tz.doctype.vehicle_sync_task.processor.reset_cycle", "csf_tz.csftz_hooks.items_revaluation.process_incorrect_balance_qty", "csf_tz.stanbic.sftp.sync_all_stanbank_files", "csf_tz.stanbic.sftp.process_download_files", @@ -331,8 +327,6 @@ "csf_tz.bank_api.reconciliation", "csf_tz.csftz_hooks.additional_salary.generate_additional_salary_records", "csf_tz.csftz_hooks.exchange_calculations.update_pending_transactions", - "csf_tz.csf_tz.doctype.vehicle_sync_task.processor.seed_vehicle_sync_queue", - ], # "hourly": [ # "csf_tz.tasks.hourly" diff --git a/csf_tz/patches.txt b/csf_tz/patches.txt index 56e4c01a..aed96300 100755 --- a/csf_tz/patches.txt +++ b/csf_tz/patches.txt @@ -26,4 +26,4 @@ csf_tz.patches.custom_fields.vfd_providers_updated_custom_fields csf_tz.patches.migrate_vfd_providers_to_csf_tz execute:frappe.delete_doc_if_exists("Report", "Stock Ledger Mismatch") csf_tz.patches.delete_versions_for_vehicle_fine_record_and_parking_bill -csf_tz.patches.add_vehicle_sync_task_log_setting +csf_tz.patches.remove_vehicle_sync_task_log_setting diff --git a/csf_tz/patches/add_vehicle_sync_task_log_setting.py b/csf_tz/patches/add_vehicle_sync_task_log_setting.py deleted file mode 100644 index ae419239..00000000 --- a/csf_tz/patches/add_vehicle_sync_task_log_setting.py +++ /dev/null @@ -1,15 +0,0 @@ -import frappe - -def execute(): - if not frappe.db.exists("DocType", "Log Settings"): - return - - log_settings = frappe.get_doc("Log Settings") - - if not any(d.ref_doctype == "Vehicle Sync Task" for d in log_settings.logs_to_clear): - log_settings.append("logs_to_clear", { - "ref_doctype": "Vehicle Sync Task", - "days": 7 - }) - - log_settings.save(ignore_permissions=True) diff --git a/csf_tz/patches/remove_vehicle_sync_task_log_setting.py b/csf_tz/patches/remove_vehicle_sync_task_log_setting.py new file mode 100644 index 00000000..1ca234c9 --- /dev/null +++ b/csf_tz/patches/remove_vehicle_sync_task_log_setting.py @@ -0,0 +1,17 @@ +import frappe + + +def execute(): + if not frappe.db.exists("DocType", "Log Settings"): + return + + log_settings = frappe.get_doc("Log Settings") + rows_to_keep = [ + row for row in log_settings.logs_to_clear if row.ref_doctype != "Vehicle Sync Task" + ] + + if len(rows_to_keep) == len(log_settings.logs_to_clear): + return + + log_settings.set("logs_to_clear", rows_to_keep) + log_settings.save(ignore_permissions=True) From 32e4ccf3487c7e0a6780aea6773d8b711d78672c Mon Sep 17 00:00:00 2001 From: Emanuel Kagombora Date: Mon, 20 Apr 2026 09:43:50 +0300 Subject: [PATCH 03/18] chore(csf_tz): remove Employee OT Component and Salary Slip OT Component --- .../doctype/employee_ot_component/__init__.py | 0 .../employee_ot_component.json | 41 ---- .../employee_ot_component.py | 8 - .../salary_slip_ot_component/__init__.py | 0 .../salary_slip_ot_component.json | 41 ---- .../salary_slip_ot_component.py | 8 - csf_tz/csftz_hooks/payroll.py | 89 -------- csf_tz/hooks.py | 6 +- csf_tz/patches.txt | 7 +- .../07_employee_custom_fields.json | 196 +--------------- .../fixtures/payware_custom_field.json | 214 +----------------- .../remove_ot_component_custom_fields.py | 14 ++ 12 files changed, 22 insertions(+), 602 deletions(-) delete mode 100644 csf_tz/csf_tz/doctype/employee_ot_component/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.json delete mode 100644 csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.py delete mode 100644 csf_tz/csf_tz/doctype/salary_slip_ot_component/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.json delete mode 100644 csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.py create mode 100644 csf_tz/patches/remove_ot_component_custom_fields.py diff --git a/csf_tz/csf_tz/doctype/employee_ot_component/__init__.py b/csf_tz/csf_tz/doctype/employee_ot_component/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.json b/csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.json deleted file mode 100644 index 30410d16..00000000 --- a/csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "actions": [], - "autoname": "EOTC.#", - "creation": "2019-02-18 09:46:35.383853", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "salary_component", - "no_of_hours" - ], - "fields": [ - { - "fieldname": "salary_component", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Salary Component", - "options": "Salary Component" - }, - { - "fieldname": "no_of_hours", - "fieldtype": "Float", - "in_list_view": 1, - "label": "No of Hours" - } - ], - "istable": 1, - "links": [], - "modified": "2023-11-27 14:56:40.451485", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Employee OT Component", - "naming_rule": "Expression (old style)", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "states": [], - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.py b/csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.py deleted file mode 100644 index b7dc1189..00000000 --- a/csf_tz/csf_tz/doctype/employee_ot_component/employee_ot_component.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2023, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - -class EmployeeOTComponent(Document): - pass diff --git a/csf_tz/csf_tz/doctype/salary_slip_ot_component/__init__.py b/csf_tz/csf_tz/doctype/salary_slip_ot_component/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.json b/csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.json deleted file mode 100644 index 9ba85fe6..00000000 --- a/csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "actions": [], - "autoname": "SSOTC.#####", - "creation": "2019-02-18 09:46:16.715714", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "salary_component", - "no_of_hours" - ], - "fields": [ - { - "fieldname": "salary_component", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Salary Component", - "options": "Salary Component" - }, - { - "fieldname": "no_of_hours", - "fieldtype": "Float", - "in_list_view": 1, - "label": "No of Hours" - } - ], - "istable": 1, - "links": [], - "modified": "2023-11-27 14:58:11.001056", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Salary Slip OT Component", - "naming_rule": "Expression (old style)", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "states": [], - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.py b/csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.py deleted file mode 100644 index 786d40ef..00000000 --- a/csf_tz/csf_tz/doctype/salary_slip_ot_component/salary_slip_ot_component.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2023, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - -class SalarySlipOTComponent(Document): - pass diff --git a/csf_tz/csftz_hooks/payroll.py b/csf_tz/csftz_hooks/payroll.py index 51826de2..fb836969 100644 --- a/csf_tz/csftz_hooks/payroll.py +++ b/csf_tz/csftz_hooks/payroll.py @@ -310,95 +310,6 @@ def enqueue_apply_workflow_for_salary_slips(kwargs): continue -@frappe.whitelist() -def generate_component_in_salary_slip_update(doc, method): - if not doc.name.upper().startswith("NEW") and frappe.db.get_single_value( - "CSF TZ Settings", "ot_module" - ): - base = 0 - list = [] - - for component in doc.earnings: - if str(component.salary_component).upper() == "BASIC": - base = component.amount / doc.payment_days * doc.total_working_days - list.append(component) - if base == 0: - f"Basic Component not Found on this Salary Slip: {doc.name}" - - for component in doc.salary_slip_ot_component: - earning_dict = frappe.new_doc("Salary Detail") - earning_dict.parent = doc.name - earning_dict.parenttype = doc.doctype - earning_dict.parentfield = "earnings" - earning_dict.salary_component = component.salary_component - earning_dict.amount = calculate_amount( - base, component.no_of_hours, component.salary_component - ) - list.append(earning_dict) - - doc.earnings = [] - doc.earnings.extend(list) - doc.calculate_net_pay() - - -@frappe.whitelist() -def generate_component_in_salary_slip_insert(doc, method): - if frappe.db.get_single_value("CSF TZ Settings", "ot_module"): - doc.salary_slip_ot_component = [] - employee = frappe.get_doc("Employee", doc.employee) - doc.run_method("get_emp_and_leave_details") - base = 0 - list = [] - for component in doc.earnings: - if str(component.salary_component).upper() == "BASIC": - base = component.amount / doc.payment_days * doc.total_working_days - list.append(component) - if base == 0: - frappe.throw( - f"Basic Component not Found on this Salary Slip: {doc.name}" - ) - - for component in employee.employee_ot_component: - component.doctype = "Salary Slip OT Component" - component.parentfield = "salary_slip_ot_component" - doc.salary_slip_ot_component.append(component) - - earning_dict = frappe.new_doc("Salary Detail") - earning_dict.parent = doc.name - earning_dict.parenttype = doc.doctype - earning_dict.parentfield = "earnings" - earning_dict.salary_component = component.salary_component - earning_dict.amount = calculate_amount( - base, component.no_of_hours, component.salary_component - ) - list.append(earning_dict) - - doc.earnings = [] - doc.earnings.extend(list) - doc.calculate_net_pay() - - -@frappe.whitelist() -def calculate_amount(base, no_of_hours, salary_component): - working_hours_per_month = frappe.db.get_single_value( - "CSF TZ Settings", "working_hours_per_month" - ) - based_on_hourly_rate, hourly_rate = frappe.db.get_value( - "Salary Component", salary_component, ["based_on_hourly_rate", "hourly_rate"] - ) - if based_on_hourly_rate: - calc = ( - (flt(base) / flt(working_hours_per_month)) - * flt(no_of_hours) - * (flt(hourly_rate) / 100) - ) - return calc - else: - frappe.throw( - f"Hourly Rate not set on this Salary Component: {salary_component}, Please set it and try again." - ) - - @frappe.whitelist() def get_amounts_summary(payroll_entry): summary = { diff --git a/csf_tz/hooks.py b/csf_tz/hooks.py index 4094d3bb..66a5f635 100755 --- a/csf_tz/hooks.py +++ b/csf_tz/hooks.py @@ -247,11 +247,7 @@ "before_cancel": "csf_tz.csftz_hooks.payroll.before_cancel_payroll_entry", }, "Salary Slip": { - "before_insert": [ - "csf_tz.csftz_hooks.payroll.before_insert_salary_slip", - "csf_tz.csftz_hooks.payroll.generate_component_in_salary_slip_insert", - ], - "before_save": "csf_tz.csftz_hooks.payroll.generate_component_in_salary_slip_update", + "before_insert": "csf_tz.csftz_hooks.payroll.before_insert_salary_slip", }, "Attendance": { "validate": "csf_tz.csftz_hooks.attendance.process_overtime", diff --git a/csf_tz/patches.txt b/csf_tz/patches.txt index 56e4c01a..4d3db3cf 100755 --- a/csf_tz/patches.txt +++ b/csf_tz/patches.txt @@ -15,7 +15,7 @@ csf_tz.patches.add_custom_fields_for_employee_advance csf_tz.patches.add_custom_field_for_cusomer_suppliers_groups csf_tz.patches.fix_module_for_core_reports csf_tz.patches.create_the_stock_entry_type -csf_tz.patches.custom_fields.payroll_cost_center_custom_fields +csf_tz.patches.custom_fields.payroll_cost_center_custom_fields csf_tz.patches.update_salary_slips_from_currrent_employee_payroll_cost_center csf_tz.patches.custom_fields.delete_employee_custom_fields csf_tz.patches.delete_default_value_fields @@ -26,4 +26,7 @@ csf_tz.patches.custom_fields.vfd_providers_updated_custom_fields csf_tz.patches.migrate_vfd_providers_to_csf_tz execute:frappe.delete_doc_if_exists("Report", "Stock Ledger Mismatch") csf_tz.patches.delete_versions_for_vehicle_fine_record_and_parking_bill -csf_tz.patches.add_vehicle_sync_task_log_setting +csf_tz.patches.remove_vehicle_sync_task_log_setting +csf_tz.patches.remove_ot_component_custom_fields +execute:frappe.delete_doc_if_exists("DocType", "Employee OT Component", force=True) +execute:frappe.delete_doc_if_exists("DocType", "Salary Slip OT Component", force=True) diff --git a/csf_tz/patches/custom_fields/custom_fields_json/07_employee_custom_fields.json b/csf_tz/patches/custom_fields/custom_fields_json/07_employee_custom_fields.json index 4bc06e5b..a3eea13c 100644 --- a/csf_tz/patches/custom_fields/custom_fields_json/07_employee_custom_fields.json +++ b/csf_tz/patches/custom_fields/custom_fields_json/07_employee_custom_fields.json @@ -1,101 +1,4 @@ [ - { - "name": "Salary Slip-salary_slip_ot_component", - "owner": "Administrator", - "creation": "2025-06-03 09:54:06.679280", - "modified": "2025-06-03 09:54:06.679280", - "modified_by": "Administrator", - "docstatus": 0, - "idx": 48, - "is_system_generated": 1, - "dt": "Salary Slip", - "label": "Salary Slip OT Component", - "fieldname": "salary_slip_ot_component", - "insert_after": "overtime_components", - "length": 0, - "fieldtype": "Table", - "precision": "", - "hide_seconds": 0, - "hide_days": 0, - "options": "Salary Slip OT Component", - "sort_options": 0, - "fetch_if_empty": 0, - "collapsible": 0, - "non_negative": 0, - "reqd": 0, - "unique": 0, - "is_virtual": 0, - "read_only": 0, - "ignore_user_permissions": 0, - "hidden": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "no_copy": 0, - "allow_on_submit": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "in_global_search": 0, - "in_preview": 0, - "bold": 0, - "report_hide": 0, - "search_index": 0, - "allow_in_quick_entry": 0, - "ignore_xss_filter": 0, - "translatable": 0, - "hide_border": 0, - "show_dashboard": 0, - "permlevel": 0, - "columns": 0, - "doctype": "Custom Field" - }, - { - "name": "Salary Slip-overtime_components", - "owner": "Administrator", - "creation": "2025-06-03 09:54:06.638504", - "modified": "2025-06-03 09:54:06.638504", - "modified_by": "Administrator", - "docstatus": 0, - "idx": 47, - "is_system_generated": 1, - "dt": "Salary Slip", - "label": "Overtime Components", - "fieldname": "overtime_components", - "insert_after": "base_hour_rate", - "length": 0, - "fieldtype": "Section Break", - "precision": "", - "hide_seconds": 0, - "hide_days": 0, - "sort_options": 0, - "fetch_if_empty": 0, - "collapsible": 0, - "non_negative": 0, - "reqd": 0, - "unique": 0, - "is_virtual": 0, - "read_only": 0, - "ignore_user_permissions": 0, - "hidden": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "no_copy": 0, - "allow_on_submit": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "in_global_search": 0, - "in_preview": 0, - "bold": 0, - "report_hide": 0, - "search_index": 0, - "allow_in_quick_entry": 0, - "ignore_xss_filter": 0, - "translatable": 0, - "hide_border": 0, - "show_dashboard": 0, - "permlevel": 0, - "columns": 0, - "doctype": "Custom Field" - }, { "name": "Salary Component-hourly_rate", "owner": "Administrator", @@ -676,103 +579,6 @@ "columns": 0, "doctype": "Custom Field" }, - { - "name": "Employee-employee_ot_component", - "owner": "Administrator", - "creation": "2025-06-03 09:54:06.073795", - "modified": "2025-06-03 09:54:06.073795", - "modified_by": "Administrator", - "docstatus": 0, - "idx": 88, - "is_system_generated": 1, - "dt": "Employee", - "label": "Employee OT Component", - "fieldname": "employee_ot_component", - "insert_after": "overtime_components", - "length": 0, - "fieldtype": "Table", - "precision": "", - "hide_seconds": 0, - "hide_days": 0, - "options": "Employee OT Component", - "sort_options": 0, - "fetch_if_empty": 0, - "collapsible": 0, - "non_negative": 0, - "reqd": 0, - "unique": 0, - "is_virtual": 0, - "read_only": 0, - "ignore_user_permissions": 0, - "hidden": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "no_copy": 0, - "allow_on_submit": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "in_global_search": 0, - "in_preview": 0, - "bold": 0, - "report_hide": 0, - "search_index": 0, - "allow_in_quick_entry": 0, - "ignore_xss_filter": 0, - "translatable": 0, - "hide_border": 0, - "show_dashboard": 0, - "permlevel": 0, - "columns": 0, - "doctype": "Custom Field" - }, - { - "name": "Employee-overtime_components", - "owner": "Administrator", - "creation": "2025-06-03 09:54:06.025609", - "modified": "2025-06-03 09:54:06.025609", - "modified_by": "Administrator", - "docstatus": 0, - "idx": 87, - "is_system_generated": 1, - "dt": "Employee", - "label": "Overtime Components", - "fieldname": "overtime_components", - "insert_after": "bank_code", - "length": 0, - "fieldtype": "Section Break", - "precision": "", - "hide_seconds": 0, - "hide_days": 0, - "sort_options": 0, - "fetch_if_empty": 0, - "collapsible": 0, - "non_negative": 0, - "reqd": 0, - "unique": 0, - "is_virtual": 0, - "read_only": 0, - "ignore_user_permissions": 0, - "hidden": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "no_copy": 0, - "allow_on_submit": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "in_global_search": 0, - "in_preview": 0, - "bold": 0, - "report_hide": 0, - "search_index": 0, - "allow_in_quick_entry": 0, - "ignore_xss_filter": 0, - "translatable": 0, - "hide_border": 0, - "show_dashboard": 0, - "permlevel": 0, - "columns": 0, - "doctype": "Custom Field" - }, { "name": "Employee-bank_code", "owner": "Administrator", @@ -919,4 +725,4 @@ "columns": 0, "doctype": "Custom Field" } -] \ No newline at end of file +] diff --git a/csf_tz/patches/fixtures/payware_custom_field.json b/csf_tz/patches/fixtures/payware_custom_field.json index 4e33a9d6..5c74d2e6 100644 --- a/csf_tz/patches/fixtures/payware_custom_field.json +++ b/csf_tz/patches/fixtures/payware_custom_field.json @@ -582,112 +582,6 @@ "unique": 0, "width": null }, - { - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "doctype": "Custom Field", - "dt": "Salary Slip", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "overtime_components", - "fieldtype": "Section Break", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "hour_rate", - "label": "Overtime Components", - "length": 0, - "mandatory_depends_on": null, - "modified": "2019-12-03 16:39:40.030549", - "name": "Salary Slip-overtime_components", - "no_copy": 0, - "non_negative": 0, - "options": null, - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - }, - { - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "doctype": "Custom Field", - "dt": "Salary Slip", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "salary_slip_ot_component", - "fieldtype": "Table", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "overtime_components", - "label": "Salary Slip OT Component", - "length": 0, - "mandatory_depends_on": null, - "modified": "2019-12-03 16:39:34.526842", - "name": "Salary Slip-salary_slip_ot_component", - "no_copy": 0, - "non_negative": 0, - "options": "Salary Slip OT Component", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - }, { "allow_in_quick_entry": 0, "allow_on_submit": 0, @@ -1907,112 +1801,6 @@ "unique": 0, "width": null }, - { - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "doctype": "Custom Field", - "dt": "Employee", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "overtime_components", - "fieldtype": "Section Break", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "bank_code", - "label": "Overtime Components", - "length": 0, - "mandatory_depends_on": null, - "modified": "2019-12-02 11:04:49.873588", - "name": "Employee-overtime_components", - "no_copy": 0, - "non_negative": 0, - "options": null, - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - }, - { - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": null, - "columns": 0, - "default": null, - "depends_on": null, - "description": null, - "docstatus": 0, - "doctype": "Custom Field", - "dt": "Employee", - "fetch_from": null, - "fetch_if_empty": 0, - "fieldname": "employee_ot_component", - "fieldtype": "Table", - "hidden": 0, - "hide_border": 0, - "hide_days": 0, - "hide_seconds": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_preview": 0, - "in_standard_filter": 0, - "insert_after": "overtime_components", - "label": "Employee OT Component", - "length": 0, - "mandatory_depends_on": null, - "modified": "2019-12-02 11:04:37.206071", - "name": "Employee-employee_ot_component", - "no_copy": 0, - "non_negative": 0, - "options": "Employee OT Component", - "parent": null, - "parentfield": null, - "parenttype": null, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": null, - "read_only": 0, - "read_only_depends_on": null, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "translatable": 0, - "unique": 0, - "width": null - }, { "allow_in_quick_entry": 0, "allow_on_submit": 0, @@ -2119,4 +1907,4 @@ "unique": 0, "width": null } -] \ No newline at end of file +] diff --git a/csf_tz/patches/remove_ot_component_custom_fields.py b/csf_tz/patches/remove_ot_component_custom_fields.py new file mode 100644 index 00000000..84b40cd4 --- /dev/null +++ b/csf_tz/patches/remove_ot_component_custom_fields.py @@ -0,0 +1,14 @@ +import frappe + + +CUSTOM_FIELDS = ( + "Employee-overtime_components", + "Employee-employee_ot_component", + "Salary Slip-overtime_components", + "Salary Slip-salary_slip_ot_component", +) + + +def execute(): + for field_name in CUSTOM_FIELDS: + frappe.delete_doc_if_exists("Custom Field", field_name, force=True) From e148687c86610a7498e7b113c77381ea3d2b6097 Mon Sep 17 00:00:00 2001 From: Emanuel Kagombora Date: Mon, 20 Apr 2026 10:21:08 +0300 Subject: [PATCH 04/18] chore(parking_bill): remove parking bill doctype --- .../csf_tz/doctype/parking_bill/__init__.py | 0 .../doctype/parking_bill/parking_bill.js | 8 - .../doctype/parking_bill/parking_bill.json | 278 ------------------ .../doctype/parking_bill/parking_bill.py | 155 ---------- .../doctype/parking_bill/test_parking_bill.py | 8 - .../doctype/parking_bill_details/__init__.py | 0 .../parking_bill_details.json | 76 ----- .../parking_bill_details.py | 8 - .../doctype/parking_bill_items/__init__.py | 0 .../parking_bill_items.json | 100 ------- .../parking_bill_items/parking_bill_items.py | 8 - csf_tz/hooks.py | 3 - 12 files changed, 644 deletions(-) delete mode 100644 csf_tz/csf_tz/doctype/parking_bill/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/parking_bill/parking_bill.js delete mode 100644 csf_tz/csf_tz/doctype/parking_bill/parking_bill.json delete mode 100644 csf_tz/csf_tz/doctype/parking_bill/parking_bill.py delete mode 100644 csf_tz/csf_tz/doctype/parking_bill/test_parking_bill.py delete mode 100644 csf_tz/csf_tz/doctype/parking_bill_details/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.json delete mode 100644 csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.py delete mode 100644 csf_tz/csf_tz/doctype/parking_bill_items/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.json delete mode 100644 csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.py diff --git a/csf_tz/csf_tz/doctype/parking_bill/__init__.py b/csf_tz/csf_tz/doctype/parking_bill/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/parking_bill/parking_bill.js b/csf_tz/csf_tz/doctype/parking_bill/parking_bill.js deleted file mode 100644 index 553fb374..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill/parking_bill.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2021, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Parking Bill', { - // refresh: function(frm) { - - // } -}); diff --git a/csf_tz/csf_tz/doctype/parking_bill/parking_bill.json b/csf_tz/csf_tz/doctype/parking_bill/parking_bill.json deleted file mode 100644 index d821935f..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill/parking_bill.json +++ /dev/null @@ -1,278 +0,0 @@ -{ - "actions": [], - "autoname": "field:billreference", - "creation": "2021-09-18 23:15:04.291031", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "vehicle", - "billstatus", - "billid", - "approvedby", - "billdescription", - "billpayed", - "billreference", - "billedamount", - "billcontrolnumber", - "billequivalentamount", - "expirydate", - "generateddate", - "miscellaneousamount", - "column_break_16", - "payeremail", - "remarks", - "payerphone", - "payername", - "reminderflag", - "spsystemid", - "billpaytype", - "receivedtime", - "billcurrency", - "applicationid", - "collectioncode", - "type", - "createdby", - "itemid", - "parkingdetailsid", - "section_break_29", - "bilitems", - "parkingdetails" - ], - "fields": [ - { - "fieldname": "billstatus", - "fieldtype": "Data", - "label": "billStatus", - "read_only": 1 - }, - { - "fieldname": "billid", - "fieldtype": "Data", - "label": "billId", - "read_only": 1 - }, - { - "fieldname": "approvedby", - "fieldtype": "Data", - "label": "approvedBy", - "read_only": 1 - }, - { - "fieldname": "billdescription", - "fieldtype": "Data", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "billDescription", - "read_only": 1 - }, - { - "default": "0", - "fieldname": "billpayed", - "fieldtype": "Check", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "billPayed", - "read_only": 1 - }, - { - "fieldname": "billreference", - "fieldtype": "Data", - "in_standard_filter": 1, - "label": "billReference", - "read_only": 1, - "unique": 1 - }, - { - "fieldname": "billedamount", - "fieldtype": "Float", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "billedAmount", - "read_only": 1 - }, - { - "fieldname": "billcontrolnumber", - "fieldtype": "Data", - "label": "billControlNumber", - "read_only": 1 - }, - { - "fieldname": "billequivalentamount", - "fieldtype": "Float", - "label": "billEquivalentAmount", - "read_only": 1 - }, - { - "fieldname": "expirydate", - "fieldtype": "Date", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "expiryDate", - "read_only": 1 - }, - { - "fieldname": "generateddate", - "fieldtype": "Date", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "generatedDate", - "read_only": 1 - }, - { - "fieldname": "miscellaneousamount", - "fieldtype": "Float", - "label": "miscellaneousAmount", - "read_only": 1 - }, - { - "fieldname": "payeremail", - "fieldtype": "Data", - "label": "payerEmail", - "read_only": 1 - }, - { - "fieldname": "remarks", - "fieldtype": "Data", - "in_list_view": 1, - "label": "remarks", - "read_only": 1 - }, - { - "fieldname": "payerphone", - "fieldtype": "Data", - "label": "payerPhone", - "read_only": 1 - }, - { - "fieldname": "payername", - "fieldtype": "Data", - "label": "payerName", - "read_only": 1 - }, - { - "fieldname": "reminderflag", - "fieldtype": "Data", - "label": "reminderFlag", - "read_only": 1 - }, - { - "fieldname": "spsystemid", - "fieldtype": "Data", - "label": "spSystemId", - "read_only": 1 - }, - { - "fieldname": "billpaytype", - "fieldtype": "Data", - "label": "billPayType", - "read_only": 1 - }, - { - "fieldname": "receivedtime", - "fieldtype": "Data", - "label": "receivedTime", - "read_only": 1 - }, - { - "fieldname": "applicationid", - "fieldtype": "Data", - "label": "applicationId", - "read_only": 1 - }, - { - "fieldname": "collectioncode", - "fieldtype": "Data", - "label": "collectionCode", - "read_only": 1 - }, - { - "fieldname": "type", - "fieldtype": "Data", - "label": "type", - "read_only": 1 - }, - { - "fieldname": "createdby", - "fieldtype": "Data", - "label": "createdBy", - "read_only": 1 - }, - { - "fieldname": "itemid", - "fieldtype": "Data", - "label": "itemId", - "read_only": 1 - }, - { - "fieldname": "parkingdetailsid", - "fieldtype": "Data", - "label": "parkingDetailsId", - "read_only": 1 - }, - { - "fieldname": "bilitems", - "fieldtype": "Table", - "label": "BilItems", - "options": "Parking Bill Items", - "read_only": 1 - }, - { - "fieldname": "column_break_16", - "fieldtype": "Column Break", - "read_only": 1 - }, - { - "fieldname": "section_break_29", - "fieldtype": "Section Break", - "read_only": 1 - }, - { - "fieldname": "vehicle", - "fieldtype": "Link", - "label": "Vehicle", - "options": "Vehicle", - "read_only": 1 - }, - { - "fieldname": "parkingdetails", - "fieldtype": "Table", - "label": "parkingDetails", - "options": "Parking Bill Details", - "read_only": 1 - }, - { - "fieldname": "billcurrency", - "fieldtype": "Data", - "label": "currency", - "read_only": 1 - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified": "2021-09-20 01:04:22.385365", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Parking Bill", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "vehicle", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/parking_bill/parking_bill.py b/csf_tz/csf_tz/doctype/parking_bill/parking_bill.py deleted file mode 100644 index c1cd7b95..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill/parking_bill.py +++ /dev/null @@ -1,155 +0,0 @@ -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -import json -import re -import frappe -from frappe import _ -from frappe.utils import getdate -import requests -from requests.exceptions import Timeout -from frappe.model.document import Document - - -class ParkingBill(Document): - pass - -@frappe.whitelist() -def check_bills_all_vehicles(): - plate_list = frappe.get_all("Vehicle", fields=['name', 'number_plate', 'license_plate']) - - for vehicle in plate_list: - number_plate = vehicle.get("number_plate") or vehicle.get("license_plate") - vehicle_name = vehicle.get("name") - - if number_plate: - try: - bill = get_bills(number_plate) - - # If bills are found (code 6000) - if bill and bill.code == 6000: - update_bill(vehicle_name, bill) - - # If all bills are paid or no record found (code 6004) - elif bill and bill.code == 6004: - mark_all_bills_as_paid(vehicle_name) - frappe.log_error(f"Vehicle {vehicle_name} ({number_plate}) has no unpaid bills. Marked as paid.") - - except Exception as e: - frappe.log_error(frappe.get_traceback(), str(e)) - - frappe.db.commit() - - -def get_bills(number_plate): - headers = { - 'x-transfer-key': 'e9f3e572-db87-4eff-9ed6-66922f1f7f24', - } - - url = ( - "http://termis.tarura.go.tz:6003/termis-parking-service/api/v1/parkingDetails/debts/plateNumber/" - + number_plate - ) - try: - response = requests.get(url=url, headers=headers, timeout=5) - - if response.status_code == 200: - return frappe._dict(json.loads(response.text)) - else: - res = None - try: - res = json.loads(response.text) - except: - res = response.text - frappe.log_error(res) - return None - - except Timeout: - frappe.log_error(_("Timeout error for plate {0}").format(number_plate)) - return None - except Exception as e: - frappe.log_error(e) - return None - - -def update_bill(name, bills): - if not bills.get("data"): - return - for row in bills.data: - row = frappe._dict(row) - data = frappe._dict(row.bill) - - if frappe.db.exists("Parking Bill", data.billReference): - doc = frappe.get_doc("Parking Bill", data.billReference) - else: - doc = frappe.new_doc("Parking Bill") - doc.billreference = data.billReference - - doc.vehicle = name - doc.billstatus = row.billStatus - doc.billid = data.billId - doc.approvedby = data.approvedBy - doc.billdescription = data.billDescription - doc.billpayed = 1 if data.billPayed else 0 - doc.billedamount = data.billedAmount - doc.billcontrolnumber = data.billControlNumber - doc.billequivalentamount = data.billEquivalentAmount - doc.expirydate = getdate(data.expiryDate) - doc.generateddate = getdate(data.generatedDate) - doc.miscellaneousamount = data.miscellaneousAmount - doc.payeremail = data.payerEmail - doc.remarks = data.remarks - doc.payerphone = data.payerPhone - doc.payername = data.payerName - doc.reminderflag = data.reminderFlag - doc.spsystemid = data.spSystemId - doc.billpaytype = data.billPayType - doc.receivedtime = data.receivedTime - doc.billcurrency = data.currency - doc.applicationid = data.applicationId - doc.collectioncode = data.collectionCode - doc.type = data.type - doc.createdby = data.createdBy - doc.itemid = data.itemId - doc.parkingdetailsid = data.parkingDetailsId - - doc.bilitems = [] - for item in data.billItems: - item = frappe._dict(item) - bill_item = doc.append("bilitems", {}) - bill_item.billitemrefid = item.billItemRefId - bill_item.billitemref = item.billItemRef - bill_item.billitemamount = item.billItemAmount - bill_item.billitemmiscamount = item.billItemMiscAmount - bill_item.billitemeqvamount = item.billItemEqvAmount - bill_item.billitemdescription = item.billItemDescription - bill_item.date = item.date - bill_item.sourcename = item.isourceName - bill_item.gsfcode = item.gsfCode - bill_item.parkingdetailsid = item.parkingDetailsId - - doc.parkingdetails = [] - for det in row.parkingDetails: - det = frappe._dict(det) - detail = doc.append("parkingdetails", {}) - detail.id = det.id - detail.collectorid = det.icollectorIdd - detail.councilcode = det.councilCode - detail.intime = det.inTime - detail.outtime = det.outTime - detail.detailinsertionstatus = det.detailInsertionStatus.get("description") - detail.coordinates = det.coordinates - - doc.save(ignore_permissions=True) - - -def mark_all_bills_as_paid(vehicle_name): - """ - Marks all unpaid bills for the given vehicle as paid when the API response indicates all bills are cleared. - """ - unpaid_bills = frappe.get_all("Parking Bill", filters={'vehicle': vehicle_name, 'billpayed': 0}) - - for bill in unpaid_bills: - doc = frappe.get_doc("Parking Bill", bill['name']) - doc.billpayed = 1 # Mark the bill as paid - doc.save(ignore_permissions=True) diff --git a/csf_tz/csf_tz/doctype/parking_bill/test_parking_bill.py b/csf_tz/csf_tz/doctype/parking_bill/test_parking_bill.py deleted file mode 100644 index 9e125d13..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill/test_parking_bill.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Aakvatech and Contributors -# See license.txt - -# import frappe -import unittest - -class TestParkingBill(unittest.TestCase): - pass diff --git a/csf_tz/csf_tz/doctype/parking_bill_details/__init__.py b/csf_tz/csf_tz/doctype/parking_bill_details/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.json b/csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.json deleted file mode 100644 index b75677c8..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "actions": [], - "creation": "2021-09-18 23:39:04.042497", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "id", - "collectorid", - "councilcode", - "intime", - "outtime", - "detailinsertionstatus", - "coordinates" - ], - "fields": [ - { - "fieldname": "id", - "fieldtype": "Data", - "label": "id", - "read_only": 1 - }, - { - "fieldname": "collectorid", - "fieldtype": "Data", - "label": "collectorId", - "read_only": 1 - }, - { - "fieldname": "councilcode", - "fieldtype": "Data", - "label": "councilCode", - "read_only": 1 - }, - { - "fieldname": "intime", - "fieldtype": "Datetime", - "in_list_view": 1, - "label": "inTime", - "read_only": 1 - }, - { - "fieldname": "outtime", - "fieldtype": "Datetime", - "in_list_view": 1, - "label": "outTime", - "read_only": 1 - }, - { - "fieldname": "detailinsertionstatus", - "fieldtype": "Data", - "in_list_view": 1, - "label": "detailInsertionStatus", - "read_only": 1 - }, - { - "fieldname": "coordinates", - "fieldtype": "Data", - "in_list_view": 1, - "label": "coordinates", - "read_only": 1 - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2021-09-18 23:45:04.557419", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Parking Bill Details", - "owner": "Administrator", - "permissions": [], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.py b/csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.py deleted file mode 100644 index 07f4d23a..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill_details/parking_bill_details.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - -class ParkingBillDetails(Document): - pass diff --git a/csf_tz/csf_tz/doctype/parking_bill_items/__init__.py b/csf_tz/csf_tz/doctype/parking_bill_items/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.json b/csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.json deleted file mode 100644 index 29cc0821..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "actions": [], - "creation": "2021-09-18 23:17:43.420193", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "billitemrefid", - "billitemref", - "billitemamount", - "billitemmiscamount", - "billitemeqvamount", - "billitemdescription", - "date", - "sourcename", - "gsfcode", - "parkingdetailsid" - ], - "fields": [ - { - "fieldname": "billitemrefid", - "fieldtype": "Data", - "in_list_view": 1, - "label": "billItemRefId", - "read_only": 1 - }, - { - "fieldname": "billitemref", - "fieldtype": "Data", - "in_list_view": 1, - "label": "billItemRef", - "read_only": 1 - }, - { - "fieldname": "billitemamount", - "fieldtype": "Float", - "in_list_view": 1, - "label": "billItemAmount", - "read_only": 1 - }, - { - "fieldname": "billitemmiscamount", - "fieldtype": "Float", - "label": "billItemMiscAmount", - "read_only": 1 - }, - { - "fieldname": "billitemeqvamount", - "fieldtype": "Float", - "label": "billItemEqvAmount", - "read_only": 1 - }, - { - "fieldname": "billitemdescription", - "fieldtype": "Data", - "in_list_view": 1, - "label": "billItemDescription", - "read_only": 1 - }, - { - "fieldname": "date", - "fieldtype": "Date", - "in_list_view": 1, - "label": "date", - "read_only": 1 - }, - { - "fieldname": "sourcename", - "fieldtype": "Data", - "in_list_view": 1, - "label": "sourceName", - "read_only": 1 - }, - { - "fieldname": "gsfcode", - "fieldtype": "Data", - "in_list_view": 1, - "label": "gsfCode", - "read_only": 1 - }, - { - "fieldname": "parkingdetailsid", - "fieldtype": "Data", - "label": "parkingDetailsId", - "read_only": 1 - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2021-09-18 23:19:27.317425", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Parking Bill Items", - "owner": "Administrator", - "permissions": [], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.py b/csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.py deleted file mode 100644 index 5f58448f..00000000 --- a/csf_tz/csf_tz/doctype/parking_bill_items/parking_bill_items.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - -class ParkingBillItems(Document): - pass diff --git a/csf_tz/hooks.py b/csf_tz/hooks.py index 4094d3bb..60facd12 100755 --- a/csf_tz/hooks.py +++ b/csf_tz/hooks.py @@ -298,9 +298,6 @@ "* * * * *": [ "csf_tz.csf_tz.doctype.vehicle_sync_task.processor.run_vehicle_batch" ], - "0 */6 * * *": [ - "csf_tz.csf_tz.doctype.parking_bill.parking_bill.check_bills_all_vehicles", - ], "0 */2 * * *": [ "csf_tz.csf_tz.doctype.vehicle_fine_record.vehicle_fine_record.check_fine_all_vehicles", ], From bbaa0f727c583c72daac394a879e4fa20542a50a Mon Sep 17 00:00:00 2001 From: Emanuel Kagombora Date: Mon, 20 Apr 2026 10:54:33 +0300 Subject: [PATCH 05/18] chore(piecework): remove piecework with its configurations --- csf_tz/config/hr.py | 21 --- csf_tz/config/payroll.py | 21 --- .../__init__.py | 0 .../employee_piecework_additional_salary.json | 50 ------ .../employee_piecework_additional_salary.py | 8 - csf_tz/csf_tz/doctype/piecework/__init__.py | 0 csf_tz/csf_tz/doctype/piecework/piecework.js | 27 --- .../csf_tz/doctype/piecework/piecework.json | 157 ------------------ csf_tz/csf_tz/doctype/piecework/piecework.py | 42 ----- .../doctype/piecework/test_piecework.py | 10 -- .../piecework_payment_allocation/__init__.py | 0 .../piecework_payment_allocation.js | 8 - .../piecework_payment_allocation.json | 55 ------ .../piecework_payment_allocation.py | 10 -- .../test_piecework_payment_allocation.py | 10 -- .../piecework_salary_disbursement/__init__.py | 0 .../piecework_salary_disbursement.js | 8 - .../piecework_salary_disbursement.json | 85 ---------- .../piecework_salary_disbursement.py | 8 - .../test_piecework_salary_disbursement.py | 8 - .../doctype/piecework_single/__init__.py | 0 .../piecework_single/piecework_single.js | 28 ---- .../piecework_single/piecework_single.json | 107 ------------ .../piecework_single/piecework_single.py | 34 ---- .../piecework_single/test_piecework_single.py | 10 -- .../csf_tz/doctype/piecework_type/__init__.py | 0 .../doctype/piecework_type/piecework_type.js | 8 - .../piecework_type/piecework_type.json | 91 ---------- .../doctype/piecework_type/piecework_type.py | 10 -- .../piecework_type/test_piecework_type.py | 10 -- .../single_piecework_employees/__init__.py | 0 .../single_piecework_employees.json | 114 ------------- .../single_piecework_employees.py | 10 -- .../fixtures/old_fixtures_from_hooks.py | 1 - csf_tz/patches/fixtures/property_setter.json | 17 -- .../property_setter/property_setter.py | 8 +- csf_tz/piecework/__init__.py | 0 csf_tz/piecework/report/__init__.py | 0 .../report/piecework_net_pay/__init__.py | 0 .../piecework_net_pay/piecework_net_pay.json | 49 ------ 40 files changed, 1 insertion(+), 1024 deletions(-) delete mode 100644 csf_tz/config/hr.py delete mode 100644 csf_tz/config/payroll.py delete mode 100644 csf_tz/csf_tz/doctype/employee_piecework_additional_salary/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.json delete mode 100644 csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.py delete mode 100644 csf_tz/csf_tz/doctype/piecework/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/piecework/piecework.js delete mode 100644 csf_tz/csf_tz/doctype/piecework/piecework.json delete mode 100644 csf_tz/csf_tz/doctype/piecework/piecework.py delete mode 100644 csf_tz/csf_tz/doctype/piecework/test_piecework.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_payment_allocation/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.js delete mode 100644 csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.json delete mode 100644 csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_payment_allocation/test_piecework_payment_allocation.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_salary_disbursement/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.js delete mode 100644 csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.json delete mode 100644 csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_salary_disbursement/test_piecework_salary_disbursement.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_single/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_single/piecework_single.js delete mode 100644 csf_tz/csf_tz/doctype/piecework_single/piecework_single.json delete mode 100644 csf_tz/csf_tz/doctype/piecework_single/piecework_single.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_single/test_piecework_single.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_type/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_type/piecework_type.js delete mode 100644 csf_tz/csf_tz/doctype/piecework_type/piecework_type.json delete mode 100644 csf_tz/csf_tz/doctype/piecework_type/piecework_type.py delete mode 100644 csf_tz/csf_tz/doctype/piecework_type/test_piecework_type.py delete mode 100644 csf_tz/csf_tz/doctype/single_piecework_employees/__init__.py delete mode 100644 csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.json delete mode 100644 csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.py delete mode 100644 csf_tz/piecework/__init__.py delete mode 100644 csf_tz/piecework/report/__init__.py delete mode 100644 csf_tz/piecework/report/piecework_net_pay/__init__.py delete mode 100644 csf_tz/piecework/report/piecework_net_pay/piecework_net_pay.json diff --git a/csf_tz/config/hr.py b/csf_tz/config/hr.py deleted file mode 100644 index 6922e116..00000000 --- a/csf_tz/config/hr.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Piecework"), - "items": [ - { - "label": "Piecework Type", - "name": "Piecework Type", - "type": "doctype" - }, - { - "label": "Piecework", - "name": "Piecework", - "type": "doctype" - } - ] - } - ] \ No newline at end of file diff --git a/csf_tz/config/payroll.py b/csf_tz/config/payroll.py deleted file mode 100644 index 6922e116..00000000 --- a/csf_tz/config/payroll.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from frappe import _ - -def get_data(): - return [ - { - "label": _("Piecework"), - "items": [ - { - "label": "Piecework Type", - "name": "Piecework Type", - "type": "doctype" - }, - { - "label": "Piecework", - "name": "Piecework", - "type": "doctype" - } - ] - } - ] \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/__init__.py b/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.json b/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.json deleted file mode 100644 index ca7633c7..00000000 --- a/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "actions": [], - "creation": "2021-07-01 18:12:28.104243", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "employee", - "employee_name", - "amount", - "additional_salary" - ], - "fields": [ - { - "fieldname": "employee", - "fieldtype": "Link", - "label": "Employee", - "options": "Employee" - }, - { - "fieldname": "amount", - "fieldtype": "Currency", - "label": "Amount" - }, - { - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "label": "Employee Name" - }, - { - "fieldname": "additional_salary", - "fieldtype": "Link", - "label": "Additional Salary", - "options": "Additional Salary" - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2021-07-01 18:13:45.444494", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Employee Piecework Additional Salary", - "owner": "Administrator", - "permissions": [], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.py b/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.py deleted file mode 100644 index 187b7339..00000000 --- a/csf_tz/csf_tz/doctype/employee_piecework_additional_salary/employee_piecework_additional_salary.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - -class EmployeePieceworkAdditionalSalary(Document): - pass diff --git a/csf_tz/csf_tz/doctype/piecework/__init__.py b/csf_tz/csf_tz/doctype/piecework/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/piecework/piecework.js b/csf_tz/csf_tz/doctype/piecework/piecework.js deleted file mode 100644 index 73954746..00000000 --- a/csf_tz/csf_tz/doctype/piecework/piecework.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2021, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on("Piecework", { - task: (frm) => setTotal(frm), - quantity: (frm) => setTotal(frm), - task_rate: (frm) => setTotal(frm), - - setup: (frm) => { - frm.set_query("task", () => { - return { - filters: { - disabled: 0, - }, - }; - }); - }, -}); - -const setTotal = (frm) => { - const total = frm.doc.task_rate * frm.doc.quantity || 0; - frm.set_value("total", total); - const count = frm.doc.employees.length; - frm.doc.employees.forEach((row) => { - frappe.model.set_value(row.doctype, row.name, "amount", total / count); - }); -}; diff --git a/csf_tz/csf_tz/doctype/piecework/piecework.json b/csf_tz/csf_tz/doctype/piecework/piecework.json deleted file mode 100644 index ad1b55c0..00000000 --- a/csf_tz/csf_tz/doctype/piecework/piecework.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "autoname": "format:{date}-{task}-{######}", - "creation": "2021-01-17 00:13:39.930551", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "date", - "column_break_2", - "company", - "section_break_3", - "task", - "quantity", - "column_break_6", - "task_name", - "task_rate", - "total", - "section_break_9", - "employees", - "amended_from" - ], - "fields": [ - { - "fieldname": "date", - "fieldtype": "Date", - "in_list_view": 1, - "label": "Date", - "reqd": 1 - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "section_break_3", - "fieldtype": "Section Break" - }, - { - "fieldname": "task", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Task", - "options": "Piecework Type", - "reqd": 1 - }, - { - "fieldname": "quantity", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Quantity", - "reqd": 1 - }, - { - "fieldname": "column_break_6", - "fieldtype": "Column Break" - }, - { - "fetch_from": "task.rate", - "fieldname": "task_rate", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Task Rate", - "precision": "2", - "read_only": 1 - }, - { - "fieldname": "total", - "fieldtype": "Currency", - "label": "Total", - "read_only": 1 - }, - { - "fieldname": "section_break_9", - "fieldtype": "Section Break" - }, - { - "fieldname": "employees", - "fieldtype": "Table", - "label": "Employees", - "options": "Piecework Payment Allocation", - "reqd": 1 - }, - { - "fieldname": "company", - "fieldtype": "Link", - "label": "Company", - "options": "Company", - "reqd": 1 - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Piecework", - "print_hide": 1, - "read_only": 1 - }, - { - "fetch_from": "task.task_name", - "fieldname": "task_name", - "fieldtype": "Data", - "label": "Task Name", - "read_only": 1 - } - ], - "is_submittable": 1, - "modified": "2021-04-23 23:42:01.650310", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Piecework", - "owner": "Administrator", - "permissions": [ - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "submit": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/piecework/piecework.py b/csf_tz/csf_tz/doctype/piecework/piecework.py deleted file mode 100644 index 816509c5..00000000 --- a/csf_tz/csf_tz/doctype/piecework/piecework.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe -from frappe import _ -from frappe.model.document import Document - - -class Piecework(Document): - def before_submit(self): - create_additional_salaries(self) - - def validate(self): - self.total = self.quantity * frappe.db.get_value('Piecework Type', self.task, 'rate') - employees = [] - amount = self.total / len(self.employees) - for row in self.employees: - if row.employee not in employees: - employees.append(row.employee) - row.amount = amount - else: - frappe.throw( - "The employee '{0}' is this duplicate in the table in row {1}".format(row.employee, row.idx)) - - -def create_additional_salaries(doc): - for row in doc.employees: - if row.employee and row.amount: - as_doc = frappe.new_doc("Additional Salary") - as_doc.employee = row.employee - as_doc.salary_component = 'Piecework' - as_doc.amount = row.amount - as_doc.payroll_date = doc.date - as_doc.company = doc.company - as_doc.overwrite_salary_structure_amount = 0 - as_doc.insert(ignore_permissions=True) - row.additional_salary = as_doc.name - as_doc.submit() - frappe.msgprint(_("Additional Salary {0} created for employee {1}").format( - as_doc.name, row.employee), alert=True) diff --git a/csf_tz/csf_tz/doctype/piecework/test_piecework.py b/csf_tz/csf_tz/doctype/piecework/test_piecework.py deleted file mode 100644 index 76d80cdf..00000000 --- a/csf_tz/csf_tz/doctype/piecework/test_piecework.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and Contributors -# See license.txt -from __future__ import unicode_literals - -# import frappe -import unittest - -class TestPiecework(unittest.TestCase): - pass diff --git a/csf_tz/csf_tz/doctype/piecework_payment_allocation/__init__.py b/csf_tz/csf_tz/doctype/piecework_payment_allocation/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.js b/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.js deleted file mode 100644 index f9c867e9..00000000 --- a/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2021, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Piecework Payment Allocation', { - // refresh: function(frm) { - - // } -}); diff --git a/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.json b/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.json deleted file mode 100644 index 3e90ccdd..00000000 --- a/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "creation": "2021-01-17 00:05:31.021900", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "employee", - "employee_name", - "amount", - "additional_salary" - ], - "fields": [ - { - "fieldname": "employee", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Employee", - "options": "Employee", - "reqd": 1 - }, - { - "fieldname": "amount", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Amount", - "precision": "2", - "read_only": 1 - }, - { - "fieldname": "additional_salary", - "fieldtype": "Link", - "label": "Additional Salary", - "options": "Additional Salary", - "read_only": 1 - }, - { - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Employee Name" - } - ], - "istable": 1, - "modified": "2021-02-12 12:15:58.721685", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Piecework Payment Allocation", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.py b/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.py deleted file mode 100644 index 0ac6caaa..00000000 --- a/csf_tz/csf_tz/doctype/piecework_payment_allocation/piecework_payment_allocation.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -# import frappe -from frappe.model.document import Document - -class PieceworkPaymentAllocation(Document): - pass diff --git a/csf_tz/csf_tz/doctype/piecework_payment_allocation/test_piecework_payment_allocation.py b/csf_tz/csf_tz/doctype/piecework_payment_allocation/test_piecework_payment_allocation.py deleted file mode 100644 index 9d219fb2..00000000 --- a/csf_tz/csf_tz/doctype/piecework_payment_allocation/test_piecework_payment_allocation.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and Contributors -# See license.txt -from __future__ import unicode_literals - -# import frappe -import unittest - -class TestPieceworkPaymentAllocation(unittest.TestCase): - pass diff --git a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/__init__.py b/csf_tz/csf_tz/doctype/piecework_salary_disbursement/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.js b/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.js deleted file mode 100644 index 9cd1b1ae..00000000 --- a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2021, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Piecework Salary Disbursement', { - // refresh: function(frm) { - - // } -}); diff --git a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.json b/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.json deleted file mode 100644 index 9b61011d..00000000 --- a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "actions": [], - "autoname": "format:start_date-end_date-######", - "creation": "2021-07-01 18:11:07.506913", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "start_date", - "end_date", - "payroll_date", - "column_break_3", - "earning_salary_component", - "deduction_salary_component", - "section_break_6", - "employee" - ], - "fields": [ - { - "fieldname": "start_date", - "fieldtype": "Date", - "label": "Start Date" - }, - { - "fieldname": "end_date", - "fieldtype": "Date", - "label": "End Date" - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "payroll_date", - "fieldtype": "Date", - "label": "Payroll Date" - }, - { - "fieldname": "section_break_6", - "fieldtype": "Section Break" - }, - { - "fieldname": "employee", - "fieldtype": "Table", - "label": "Employee", - "options": "Employee Piecework Additional Salary" - }, - { - "fieldname": "earning_salary_component", - "fieldtype": "Link", - "label": "Earning Salary Component ", - "options": "Salary Component" - }, - { - "fieldname": "deduction_salary_component", - "fieldtype": "Link", - "label": "Deduction Salary Component", - "options": "Salary Component" - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified": "2021-07-03 12:37:00.405085", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Piecework Salary Disbursement", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.py b/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.py deleted file mode 100644 index aa5d0913..00000000 --- a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/piecework_salary_disbursement.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - -class PieceworkSalaryDisbursement(Document): - pass diff --git a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/test_piecework_salary_disbursement.py b/csf_tz/csf_tz/doctype/piecework_salary_disbursement/test_piecework_salary_disbursement.py deleted file mode 100644 index c9805c0d..00000000 --- a/csf_tz/csf_tz/doctype/piecework_salary_disbursement/test_piecework_salary_disbursement.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Aakvatech and Contributors -# See license.txt - -# import frappe -import unittest - -class TestPieceworkSalaryDisbursement(unittest.TestCase): - pass diff --git a/csf_tz/csf_tz/doctype/piecework_single/__init__.py b/csf_tz/csf_tz/doctype/piecework_single/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/piecework_single/piecework_single.js b/csf_tz/csf_tz/doctype/piecework_single/piecework_single.js deleted file mode 100644 index e90676d0..00000000 --- a/csf_tz/csf_tz/doctype/piecework_single/piecework_single.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2021, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Piecework Single', { - // refresh: function(frm) { - - // } -}); - -frappe.ui.form.on('Single Piecework Employees', { - task: (frm, cdt, cdn) => { - const row = locals[cdt][cdn]; - setTotal(frm, row); - }, - task_rate: (frm, cdt, cdn) => { - const row = locals[cdt][cdn]; - setTotal(frm, row); - }, - quantity: (frm, cdt, cdn) => { - const row = locals[cdt][cdn]; - setTotal(frm, row); - }, -}); - -const setTotal = (frm, row) => { - const total = row.task_rate * row.quantity || 0; - frappe.model.set_value(row.doctype, row.name, "amount", total); -}; \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/piecework_single/piecework_single.json b/csf_tz/csf_tz/doctype/piecework_single/piecework_single.json deleted file mode 100644 index e7f17284..00000000 --- a/csf_tz/csf_tz/doctype/piecework_single/piecework_single.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "autoname": "format:{date}-{task}-{######}", - "creation": "2021-04-23 23:12:51.189256", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "date", - "column_break_2", - "company", - "section_break_4", - "employees", - "amended_from" - ], - "fields": [ - { - "default": "Today", - "fieldname": "date", - "fieldtype": "Date", - "label": "Date", - "reqd": 1 - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "company", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Company", - "options": "Company", - "reqd": 1 - }, - { - "fieldname": "section_break_4", - "fieldtype": "Section Break" - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Piecework Single", - "print_hide": 1, - "read_only": 1 - }, - { - "fieldname": "employees", - "fieldtype": "Table", - "label": "Employees", - "options": "Single Piecework Employees", - "reqd": 1 - } - ], - "is_submittable": 1, - "modified": "2021-04-27 00:07:03.606305", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Piecework Single", - "owner": "Administrator", - "permissions": [ - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "submit": 1, - "write": 1 - }, - { - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "share": 1, - "submit": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "share": 1, - "write": 1 - } - ], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/piecework_single/piecework_single.py b/csf_tz/csf_tz/doctype/piecework_single/piecework_single.py deleted file mode 100644 index 538f8a67..00000000 --- a/csf_tz/csf_tz/doctype/piecework_single/piecework_single.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe -from frappe import _ -from frappe.model.document import Document - - -class PieceworkSingle(Document): - def before_submit(self): - create_additional_salaries(self) - - -def create_additional_salaries(doc): - for row in doc.employees: - if row.employee and row.amount: - as_doc = frappe.new_doc("Additional Salary") - as_doc.employee = row.employee - as_doc.salary_component = "Piecework" - as_doc.amount = row.amount - as_doc.payroll_date = doc.date - as_doc.company = doc.company - as_doc.overwrite_salary_structure_amount = 0 - as_doc.insert(ignore_permissions=True) - row.additional_salary = as_doc.name - as_doc.submit() - frappe.msgprint( - _("Additional Salary {0} created for employee {1}").format( - as_doc.name, row.employee - ), - alert=True, - ) diff --git a/csf_tz/csf_tz/doctype/piecework_single/test_piecework_single.py b/csf_tz/csf_tz/doctype/piecework_single/test_piecework_single.py deleted file mode 100644 index d0f6a26f..00000000 --- a/csf_tz/csf_tz/doctype/piecework_single/test_piecework_single.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and Contributors -# See license.txt -from __future__ import unicode_literals - -# import frappe -import unittest - -class TestPieceworkSingle(unittest.TestCase): - pass diff --git a/csf_tz/csf_tz/doctype/piecework_type/__init__.py b/csf_tz/csf_tz/doctype/piecework_type/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/piecework_type/piecework_type.js b/csf_tz/csf_tz/doctype/piecework_type/piecework_type.js deleted file mode 100644 index b7ec93a3..00000000 --- a/csf_tz/csf_tz/doctype/piecework_type/piecework_type.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2021, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Piecework Type', { - // refresh: function(frm) { - - // } -}); diff --git a/csf_tz/csf_tz/doctype/piecework_type/piecework_type.json b/csf_tz/csf_tz/doctype/piecework_type/piecework_type.json deleted file mode 100644 index 70479884..00000000 --- a/csf_tz/csf_tz/doctype/piecework_type/piecework_type.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "autoname": "format:{task_code}", - "creation": "2021-01-17 00:02:10.540373", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "task_code", - "task_name", - "column_break_3", - "rate", - "uom", - "disabled", - "section_break_6", - "description" - ], - "fields": [ - { - "fieldname": "task_code", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Task Code", - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "task_name", - "fieldtype": "Data", - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Task Name", - "reqd": 1 - }, - { - "fieldname": "column_break_3", - "fieldtype": "Column Break" - }, - { - "fieldname": "rate", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Rate", - "reqd": 1 - }, - { - "fieldname": "uom", - "fieldtype": "Link", - "label": "UOM", - "options": "UOM" - }, - { - "fieldname": "section_break_6", - "fieldtype": "Section Break" - }, - { - "fieldname": "description", - "fieldtype": "Text", - "label": "Description" - }, - { - "default": "0", - "fieldname": "disabled", - "fieldtype": "Check", - "label": "Disabled" - } - ], - "modified": "2021-02-12 12:58:32.138100", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Piecework Type", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/piecework_type/piecework_type.py b/csf_tz/csf_tz/doctype/piecework_type/piecework_type.py deleted file mode 100644 index ec0e71f1..00000000 --- a/csf_tz/csf_tz/doctype/piecework_type/piecework_type.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -# import frappe -from frappe.model.document import Document - -class PieceworkType(Document): - pass diff --git a/csf_tz/csf_tz/doctype/piecework_type/test_piecework_type.py b/csf_tz/csf_tz/doctype/piecework_type/test_piecework_type.py deleted file mode 100644 index aa7491b3..00000000 --- a/csf_tz/csf_tz/doctype/piecework_type/test_piecework_type.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and Contributors -# See license.txt -from __future__ import unicode_literals - -# import frappe -import unittest - -class TestPieceworkType(unittest.TestCase): - pass diff --git a/csf_tz/csf_tz/doctype/single_piecework_employees/__init__.py b/csf_tz/csf_tz/doctype/single_piecework_employees/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.json b/csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.json deleted file mode 100644 index 744e8729..00000000 --- a/csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "creation": "2021-04-23 23:21:59.054525", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "employee", - "column_break_2", - "employee_name", - "section_break_4", - "task", - "column_break_6", - "task_name", - "task_rate", - "section_break_9", - "quantity", - "column_break_10", - "amount", - "section_break_11", - "additional_salary" - ], - "fields": [ - { - "fieldname": "employee", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Employee", - "options": "Employee" - }, - { - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Employee Name", - "read_only": 1 - }, - { - "fieldname": "quantity", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Quantity" - }, - { - "default": "0", - "fieldname": "amount", - "fieldtype": "Currency", - "in_list_view": 1, - "label": "Amount", - "read_only": 1 - }, - { - "fieldname": "additional_salary", - "fieldtype": "Link", - "label": "Additional Salary", - "options": "Additional Salary", - "read_only": 1 - }, - { - "fieldname": "task", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Task", - "options": "Piecework Type" - }, - { - "fetch_from": "task.task_name", - "fieldname": "task_name", - "fieldtype": "Data", - "label": "Task Name" - }, - { - "fetch_from": "task.rate", - "fieldname": "task_rate", - "fieldtype": "Currency", - "label": "Task Rate" - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "section_break_4", - "fieldtype": "Section Break" - }, - { - "fieldname": "column_break_6", - "fieldtype": "Column Break" - }, - { - "fieldname": "section_break_11", - "fieldtype": "Section Break" - }, - { - "fieldname": "column_break_10", - "fieldtype": "Column Break" - }, - { - "fieldname": "section_break_9", - "fieldtype": "Section Break" - } - ], - "istable": 1, - "modified": "2021-04-27 00:01:55.824888", - "modified_by": "Administrator", - "module": "CSF TZ", - "name": "Single Piecework Employees", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.py b/csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.py deleted file mode 100644 index 2f8f04b1..00000000 --- a/csf_tz/csf_tz/doctype/single_piecework_employees/single_piecework_employees.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, Aakvatech and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -# import frappe -from frappe.model.document import Document - -class SinglePieceworkEmployees(Document): - pass diff --git a/csf_tz/patches/fixtures/old_fixtures_from_hooks.py b/csf_tz/patches/fixtures/old_fixtures_from_hooks.py index df80438c..eef89879 100644 --- a/csf_tz/patches/fixtures/old_fixtures_from_hooks.py +++ b/csf_tz/patches/fixtures/old_fixtures_from_hooks.py @@ -199,7 +199,6 @@ "Payment Reconciliation Payment-posting_date-columns", "Payment Reconciliation Payment-posting_date-in_list_view", "Payment Schedule-payment_amount-options", - "Piecework Type-search_fields", "Purchase Invoice Item-cost_center-default", "Purchase Order-letter_head-fetch_from", "Report-javascript-depends_on", diff --git a/csf_tz/patches/fixtures/property_setter.json b/csf_tz/patches/fixtures/property_setter.json index 4d525199..ebc1e845 100644 --- a/csf_tz/patches/fixtures/property_setter.json +++ b/csf_tz/patches/fixtures/property_setter.json @@ -696,23 +696,6 @@ "row_name": null, "value": "company.default_letter_head" }, - { - "default_value": null, - "doc_type": "Piecework Type", - "docstatus": 0, - "doctype": "Property Setter", - "doctype_or_field": "DocType", - "field_name": null, - "modified": "2021-02-12 13:14:23.468895", - "name": "Piecework Type-search_fields", - "parent": null, - "parentfield": null, - "parenttype": null, - "property": "search_fields", - "property_type": "Data", - "row_name": null, - "value": "task_name" - }, { "default_value": null, "doc_type": "Document Attachment", diff --git a/csf_tz/patches/property_setter/property_setter.py b/csf_tz/patches/property_setter/property_setter.py index f9fcbd9a..402b64d3 100644 --- a/csf_tz/patches/property_setter/property_setter.py +++ b/csf_tz/patches/property_setter/property_setter.py @@ -279,12 +279,6 @@ def execute(): "property_type": "Small Text", "value": "company.default_letter_head" }, - { - "doctype": "Piecework Type", - "property": "search_fields", - "property_type": "Data", - "value": "task_name" - }, { "doctype": "Document Attachment", "field_name": "attachment", @@ -532,4 +526,4 @@ def execute(): validate_fields_for_doctype=False ) -frappe.db.commit() \ No newline at end of file +frappe.db.commit() diff --git a/csf_tz/piecework/__init__.py b/csf_tz/piecework/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/piecework/report/__init__.py b/csf_tz/piecework/report/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/piecework/report/piecework_net_pay/__init__.py b/csf_tz/piecework/report/piecework_net_pay/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/piecework/report/piecework_net_pay/piecework_net_pay.json b/csf_tz/piecework/report/piecework_net_pay/piecework_net_pay.json deleted file mode 100644 index 5052444f..00000000 --- a/csf_tz/piecework/report/piecework_net_pay/piecework_net_pay.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "add_total_row": 1, - "columns": [], - "creation": "2021-07-03 12:01:00.078585", - "disable_prepared_report": 0, - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "filters": [ - { - "fieldname": "from_date", - "fieldtype": "Date", - "label": "From Date", - "mandatory": 1, - "wildcard_filter": 0 - }, - { - "fieldname": "to_date", - "fieldtype": "Date", - "label": "To Date", - "mandatory": 1, - "wildcard_filter": 0 - } - ], - "idx": 0, - "is_standard": "Yes", - "json": "{}", - "modified": "2021-07-05 17:39:33.435659", - "modified_by": "Administrator", - "module": "Piecework", - "name": "Piecework Net Pay", - "owner": "Administrator", - "prepared_report": 0, - "query": "SELECT a.employee_name AS \"Employee Name:Data:200\",\n e.bank_ac_no AS \"Bank A/C No:Data:200\",\n sum(a.amount) * 0.9 AS \"Net Pay:Currency:150\"\nFROM `tabAdditional Salary` a LEFT JOIN `tabEmployee` e ON a.employee = e.name\nWHERE a.payroll_date BETWEEN %(from_date)s AND %(to_date)s\nAND a.salary_component = 'Piecework'\nGROUP BY a.employee\nORDER by a.employee_name", - "ref_doctype": "Additional Salary", - "report_name": "Piecework Net Pay", - "report_type": "Query Report", - "roles": [ - { - "role": "HR User" - }, - { - "role": "System Manager" - }, - { - "role": "HR Manager" - } - ] -} \ No newline at end of file From 699d3b5fc8ab4f1e175c2d5939092ef59fa58f4c Mon Sep 17 00:00:00 2001 From: Emanuel Kagombora Date: Mon, 20 Apr 2026 11:13:06 +0300 Subject: [PATCH 06/18] chore(feedback_form): remove feedback form doctype and its configurations --- csf_tz/feedback/__init__.py | 0 csf_tz/feedback/doctype/__init__.py | 0 .../doctype/feedback_form/__init__.py | 0 .../doctype/feedback_form/feedback_form.js | 8 - .../doctype/feedback_form/feedback_form.json | 104 --- .../doctype/feedback_form/feedback_form.py | 9 - .../feedback_form/test_feedback_form.py | 9 - .../doctype/feedback_question/__init__.py | 0 .../feedback_question/feedback_question.json | 62 -- .../feedback_question/feedback_question.py | 9 - .../doctype/feedback_response/__init__.py | 0 .../feedback_response/feedback_response.json | 40 -- .../feedback_response/feedback_response.py | 9 - .../doctype/feedback_template/__init__.py | 0 .../feedback_template/feedback_template.js | 8 - .../feedback_template/feedback_template.json | 57 -- .../feedback_template/feedback_template.py | 9 - .../test_feedback_template.py | 9 - csf_tz/feedback/web_form/__init__.py | 0 .../training_feedback_form/__init__.py | 0 .../training_feedback_form.js | 654 ------------------ .../training_feedback_form.json | 170 ----- .../training_feedback_form.py | 5 - csf_tz/modules.txt | 1 - 24 files changed, 1163 deletions(-) delete mode 100644 csf_tz/feedback/__init__.py delete mode 100644 csf_tz/feedback/doctype/__init__.py delete mode 100644 csf_tz/feedback/doctype/feedback_form/__init__.py delete mode 100644 csf_tz/feedback/doctype/feedback_form/feedback_form.js delete mode 100644 csf_tz/feedback/doctype/feedback_form/feedback_form.json delete mode 100644 csf_tz/feedback/doctype/feedback_form/feedback_form.py delete mode 100644 csf_tz/feedback/doctype/feedback_form/test_feedback_form.py delete mode 100644 csf_tz/feedback/doctype/feedback_question/__init__.py delete mode 100644 csf_tz/feedback/doctype/feedback_question/feedback_question.json delete mode 100644 csf_tz/feedback/doctype/feedback_question/feedback_question.py delete mode 100644 csf_tz/feedback/doctype/feedback_response/__init__.py delete mode 100644 csf_tz/feedback/doctype/feedback_response/feedback_response.json delete mode 100644 csf_tz/feedback/doctype/feedback_response/feedback_response.py delete mode 100644 csf_tz/feedback/doctype/feedback_template/__init__.py delete mode 100644 csf_tz/feedback/doctype/feedback_template/feedback_template.js delete mode 100644 csf_tz/feedback/doctype/feedback_template/feedback_template.json delete mode 100644 csf_tz/feedback/doctype/feedback_template/feedback_template.py delete mode 100644 csf_tz/feedback/doctype/feedback_template/test_feedback_template.py delete mode 100644 csf_tz/feedback/web_form/__init__.py delete mode 100644 csf_tz/feedback/web_form/training_feedback_form/__init__.py delete mode 100644 csf_tz/feedback/web_form/training_feedback_form/training_feedback_form.js delete mode 100644 csf_tz/feedback/web_form/training_feedback_form/training_feedback_form.json delete mode 100644 csf_tz/feedback/web_form/training_feedback_form/training_feedback_form.py diff --git a/csf_tz/feedback/__init__.py b/csf_tz/feedback/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/doctype/__init__.py b/csf_tz/feedback/doctype/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/doctype/feedback_form/__init__.py b/csf_tz/feedback/doctype/feedback_form/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/doctype/feedback_form/feedback_form.js b/csf_tz/feedback/doctype/feedback_form/feedback_form.js deleted file mode 100644 index a2950326..00000000 --- a/csf_tz/feedback/doctype/feedback_form/feedback_form.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2025, Aakvatech and contributors -// For license information, please see license.txt - -// frappe.ui.form.on("Feedback Form", { -// refresh(frm) { - -// }, -// }); diff --git a/csf_tz/feedback/doctype/feedback_form/feedback_form.json b/csf_tz/feedback/doctype/feedback_form/feedback_form.json deleted file mode 100644 index 8cb34fb8..00000000 --- a/csf_tz/feedback/doctype/feedback_form/feedback_form.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "autoname": "format:Feedback-{DD}-{MM}-{YY}-{####}", - "creation": "2025-07-07 21:41:09.616396", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "template", - "section_break_gfnv", - "participant_name", - "column_break_wncp", - "designation", - "column_break_ldsy", - "contact_no", - "section_break_itfe", - "responses", - "dynamic_questions", - "dynamic_html" - ], - "fields": [ - { - "fieldname": "template", - "fieldtype": "Link", - "label": "Template", - "options": "Feedback Template" - }, - { - "fieldname": "participant_name", - "fieldtype": "Data", - "label": "Participant Name" - }, - { - "fieldname": "responses", - "fieldtype": "Table", - "label": "Responses", - "options": "Feedback Response" - }, - { - "fieldname": "dynamic_questions", - "fieldtype": "HTML", - "label": "Dynamic Questions" - }, - { - "fieldname": "section_break_gfnv", - "fieldtype": "Section Break" - }, - { - "fieldname": "designation", - "fieldtype": "Data", - "label": "Designation" - }, - { - "fieldname": "contact_no", - "fieldtype": "Data", - "label": "Contact No" - }, - { - "fieldname": "section_break_itfe", - "fieldtype": "Section Break" - }, - { - "fieldname": "column_break_wncp", - "fieldtype": "Column Break" - }, - { - "fieldname": "column_break_ldsy", - "fieldtype": "Column Break" - }, - { - "fieldname": "dynamic_html", - "fieldtype": "Data", - "hidden": 1, - "label": "Dynamic HTML" - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "links": [], - "modified": "2025-09-19 16:41:16.429427", - "modified_by": "Administrator", - "module": "Feedback", - "name": "Feedback Form", - "naming_rule": "Expression", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/csf_tz/feedback/doctype/feedback_form/feedback_form.py b/csf_tz/feedback/doctype/feedback_form/feedback_form.py deleted file mode 100644 index 0f766d6c..00000000 --- a/csf_tz/feedback/doctype/feedback_form/feedback_form.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class FeedbackForm(Document): - pass diff --git a/csf_tz/feedback/doctype/feedback_form/test_feedback_form.py b/csf_tz/feedback/doctype/feedback_form/test_feedback_form.py deleted file mode 100644 index c7c0eb5c..00000000 --- a/csf_tz/feedback/doctype/feedback_form/test_feedback_form.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestFeedbackForm(FrappeTestCase): - pass diff --git a/csf_tz/feedback/doctype/feedback_question/__init__.py b/csf_tz/feedback/doctype/feedback_question/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/doctype/feedback_question/feedback_question.json b/csf_tz/feedback/doctype/feedback_question/feedback_question.json deleted file mode 100644 index 7569ac42..00000000 --- a/csf_tz/feedback/doctype/feedback_question/feedback_question.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "creation": "2025-07-07 21:28:50.496524", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "question", - "fieldtype", - "options", - "reqd" - ], - "fields": [ - { - "columns": 2, - "fieldname": "question", - "fieldtype": "Small Text", - "in_list_view": 1, - "label": "Question", - "reqd": 1 - }, - { - "columns": 1, - "fieldname": "fieldtype", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Fieldtype", - "options": "\nMultiple Choice\nCheckboxes\nDropdown\nRating\nParagraph\nShort Text", - "reqd": 1 - }, - { - "columns": 3, - "fieldname": "options", - "fieldtype": "Text", - "in_list_view": 1, - "label": "Options" - }, - { - "columns": 1, - "default": "0", - "fieldname": "reqd", - "fieldtype": "Check", - "in_list_view": 1, - "label": "Mandatory" - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2025-07-28 01:19:20.533329", - "modified_by": "Administrator", - "module": "Feedback", - "name": "Feedback Question", - "owner": "Administrator", - "permissions": [], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/csf_tz/feedback/doctype/feedback_question/feedback_question.py b/csf_tz/feedback/doctype/feedback_question/feedback_question.py deleted file mode 100644 index a34c9b7a..00000000 --- a/csf_tz/feedback/doctype/feedback_question/feedback_question.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class FeedbackQuestion(Document): - pass diff --git a/csf_tz/feedback/doctype/feedback_response/__init__.py b/csf_tz/feedback/doctype/feedback_response/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/doctype/feedback_response/feedback_response.json b/csf_tz/feedback/doctype/feedback_response/feedback_response.json deleted file mode 100644 index db7d903a..00000000 --- a/csf_tz/feedback/doctype/feedback_response/feedback_response.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "creation": "2025-07-07 21:55:27.165867", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "question", - "answer" - ], - "fields": [ - { - "fieldname": "question", - "fieldtype": "Small Text", - "in_list_view": 1, - "label": "Question" - }, - { - "fieldname": "answer", - "fieldtype": "Text", - "in_list_view": 1, - "label": "Answer" - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2025-07-07 21:57:19.847691", - "modified_by": "Administrator", - "module": "Feedback", - "name": "Feedback Response", - "owner": "Administrator", - "permissions": [], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/csf_tz/feedback/doctype/feedback_response/feedback_response.py b/csf_tz/feedback/doctype/feedback_response/feedback_response.py deleted file mode 100644 index bc693ab0..00000000 --- a/csf_tz/feedback/doctype/feedback_response/feedback_response.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class FeedbackResponse(Document): - pass diff --git a/csf_tz/feedback/doctype/feedback_template/__init__.py b/csf_tz/feedback/doctype/feedback_template/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/doctype/feedback_template/feedback_template.js b/csf_tz/feedback/doctype/feedback_template/feedback_template.js deleted file mode 100644 index e0bec3f6..00000000 --- a/csf_tz/feedback/doctype/feedback_template/feedback_template.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2025, Aakvatech and contributors -// For license information, please see license.txt - -frappe.ui.form.on("Feedback Template", { - refresh(frm) { - // Placeholder for future enhancements - }, -}); diff --git a/csf_tz/feedback/doctype/feedback_template/feedback_template.json b/csf_tz/feedback/doctype/feedback_template/feedback_template.json deleted file mode 100644 index 14c3267c..00000000 --- a/csf_tz/feedback/doctype/feedback_template/feedback_template.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "actions": [], - "allow_rename": 1, - "creation": "2025-07-07 21:26:21.518771", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "template_name", - "is_active", - "feedback_question" - ], - "fields": [ - { - "fieldname": "template_name", - "fieldtype": "Data", - "label": "Template Name" - }, - { - "default": "0", - "fieldname": "is_active", - "fieldtype": "Check", - "label": "is Active" - }, - { - "fieldname": "feedback_question", - "fieldtype": "Table", - "label": "Feedback Question", - "options": "Feedback Question" - } - ], - "grid_page_length": 50, - "index_web_pages_for_search": 1, - "links": [], - "modified": "2025-07-07 21:38:43.401658", - "modified_by": "Administrator", - "module": "Feedback", - "name": "Feedback Template", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "row_format": "Dynamic", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} \ No newline at end of file diff --git a/csf_tz/feedback/doctype/feedback_template/feedback_template.py b/csf_tz/feedback/doctype/feedback_template/feedback_template.py deleted file mode 100644 index fb0be740..00000000 --- a/csf_tz/feedback/doctype/feedback_template/feedback_template.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - - -class FeedbackTemplate(Document): - pass diff --git a/csf_tz/feedback/doctype/feedback_template/test_feedback_template.py b/csf_tz/feedback/doctype/feedback_template/test_feedback_template.py deleted file mode 100644 index d4630ef6..00000000 --- a/csf_tz/feedback/doctype/feedback_template/test_feedback_template.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2025, Aakvatech and Contributors -# See license.txt - -# import frappe -from frappe.tests.utils import FrappeTestCase - - -class TestFeedbackTemplate(FrappeTestCase): - pass diff --git a/csf_tz/feedback/web_form/__init__.py b/csf_tz/feedback/web_form/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/web_form/training_feedback_form/__init__.py b/csf_tz/feedback/web_form/training_feedback_form/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/csf_tz/feedback/web_form/training_feedback_form/training_feedback_form.js b/csf_tz/feedback/web_form/training_feedback_form/training_feedback_form.js deleted file mode 100644 index 45377870..00000000 --- a/csf_tz/feedback/web_form/training_feedback_form/training_feedback_form.js +++ /dev/null @@ -1,654 +0,0 @@ -frappe.ready(() => { - // Load Font Awesome CSS first - frappe.require( - [ - "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css", - ], - initializeForm - ); - - function initializeForm() { - frappe.web_form.on("template", (_, value) => { - showLoadingState(); - fetchTemplate(value); - }); - - function showLoadingState() { - frappe.web_form.set_df_property( - "dynamic_html", - "options", - ` -
-
- Loading... -
-

Loading questions...

-
- ` - ); - } - - function fetchTemplate(templateName) { - frappe.call({ - method: "frappe.client.get", - args: { - doctype: "Feedback Template", - name: templateName, - }, - callback: handleTemplateResponse, - error: showErrorState, - }); - } - - function handleTemplateResponse(response) { - if (response.message) { - window._feedback_questions = response.message.feedback_question || []; - renderQuestions(window._feedback_questions); - } - } - - function showErrorState() { - frappe.web_form.set_df_property( - "dynamic_html", - "options", - ` -
- -

Failed to load questions. Please try again.

-
- ` - ); - } - - function renderQuestions(questions) { - let html = createFormContainer(); - - questions.forEach((q, index) => { - html += createQuestionBlock(q, index); - }); - - html += ``; // Close container - - frappe.web_form.set_df_property("dynamic_html", "options", html); - addQuestionBlockHoverEffects(); - initializeStarRatings(); - initializeClearButtons(); - setTimeout(checkAllRequiredFilled, 100); - } - - function createFormContainer() { - return ` -