diff --git a/.gitignore b/.gitignore index 14da37e..5d87a96 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ *.pyc *.egg-info *.swp +*~ tags justworks_erpnext/docs/current \ No newline at end of file diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/__init__.py b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.js b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.js new file mode 100644 index 0000000..7d5016f --- /dev/null +++ b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.js @@ -0,0 +1,34 @@ +// Copyright (c) 2020, Studio Infinity and contributors +// For license information, please see license.txt + +function process_invoice_file(frm) { + return frappe.call({ + method: "process_invoice_file", + doc: frm.doc, + callback: function(r, rt) { + frm.refresh_field("lines"); + frm.refresh_fields(); + } + }); +} + +frappe.ui.form.on('JW Import', { + // refresh: function(frm) { + + // } + setup: function(frm) { + let lff_field = frm.fields_dict.load_from_file; + lff_field.on_upload_complete = function(attachment) { + Object.getPrototypeOf(this).on_upload_complete.call(this, attachment); + this.frm.doc.load_from_file = attachment.file_url; + process_invoice_file(this.frm); + }; + }, + + load_from_file: function(frm) { + if (!frm.doc.load_from_file) { + frm.clear_table('lines'); + frm.refresh_field('lines'); + } + } +}); diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.json b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.json new file mode 100644 index 0000000..4e8318a --- /dev/null +++ b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.json @@ -0,0 +1,216 @@ +{ + "actions": [ + { + "action": "List/JW Employee Allocation", + "action_type": "Route", + "label": "Edit Allocations" + }, + { + "action": "List/JW Account Mapping", + "action_type": "Route", + "label": "Edit Accounts" + }, + { + "action": "justworks_erpnext.justworks_erpnext_connector.doctype.jw_import.jw_import.record_entries", + "action_type": "Server Action", + "label": "Record Entries" + } + ], + "creation": "2020-11-18 15:57:57.559832", + "description": "Use this Form to import the information from a Justworks Invoice Details report (as a csv file). Note the report may contain details on multiple invoices.", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "justworks_company", + "header_column_break", + "justworks_currency", + "invoice_date_section", + "start_invoice_date", + "date_column_break", + "end_invoice_date", + "accounting_dimensions_section", + "internal_cost_center", + "dimension_col_break", + "ledger_section", + "jw_obligation_account", + "jw_collection_debits", + "jw_payment_account", + "ledger_column_break", + "dim_balance_account", + "jw_collection_credits", + "auto_submit", + "invoice_section", + "load_from_file", + "lines" + ], + "fields": [ + { + "fieldname": "justworks_company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company", + "reqd": 1 + }, + { + "fieldname": "header_column_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "justworks_currency", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Currency", + "options": "Currency", + "reqd": 1 + }, + { + "collapsible": 1, + "description": "Justworks invoices outside the range defined below (if any) will be ignored.", + "fieldname": "invoice_date_section", + "fieldtype": "Section Break", + "label": "Invoice Date Filter" + }, + { + "fieldname": "start_invoice_date", + "fieldtype": "Date", + "label": "Start" + }, + { + "fieldname": "date_column_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "end_invoice_date", + "fieldtype": "Date", + "label": "End" + }, + { + "collapsible": 1, + "description": "These are the accounting dimensions that will be used for all ledger entries other than those determined by a JW Employee Allocation.", + "fieldname": "accounting_dimensions_section", + "fieldtype": "Section Break", + "label": "Internal Accounting Dimensions" + }, + { + "fieldname": "internal_cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, + { + "fieldname": "dimension_col_break", + "fieldtype": "Column Break" + }, + { + "collapsible": 1, + "fieldname": "ledger_section", + "fieldtype": "Section Break", + "label": "Ledger Settings" + }, + { + "description": "If set, expense Journal Entry records will generated for employee-related payments and credited to this account.", + "fieldname": "jw_obligation_account", + "fieldtype": "Link", + "label": "Credit Justworks Expenses To:", + "options": "Account" + }, + { + "description": "If this and the corresponding Credit account are specified, Bank Entry records for collections will be generated crediting this account.", + "fieldname": "jw_collection_debits", + "fieldtype": "Link", + "label": "Debit Justworks Collections To:", + "options": "Account" + }, + { + "description": "If specified, Payment Entry records will be generated for charges associated with Accounts of type Payable, and credited to this account.", + "fieldname": "jw_payment_account", + "fieldtype": "Link", + "label": "Credit Justworks Payments To:", + "options": "Account" + }, + { + "fieldname": "ledger_column_break", + "fieldtype": "Column Break" + }, + { + "description": "If specified, Journal Entry records will be balanced per Accounting Dimension to those specified in the Internal Accounting Dimensions, using this account for automatically-generated transfers.", + "fieldname": "dim_balance_account", + "fieldtype": "Link", + "label": "Balance Accounting Dimensions To:", + "options": "Account" + }, + { + "description": "The (typically Bank) Account that Justworks collections are credited to.", + "fieldname": "jw_collection_credits", + "fieldtype": "Link", + "label": "Credit Justworks Collections To:", + "options": "Account" + }, + { + "default": "0", + "description": "If checked, all entries generated will be automatically submitted as part of the permanent accounting records.", + "fieldname": "auto_submit", + "fieldtype": "Check", + "label": "Auto-submit?" + }, + { + "fieldname": "invoice_section", + "fieldtype": "Section Break" + }, + { + "fieldname": "lines", + "fieldtype": "Table", + "label": "Invoice Lines", + "options": "JW Invoice Line" + }, + { + "fieldname": "load_from_file", + "fieldtype": "Attach", + "label": "Load Invoices from File" + } + ], + "hide_toolbar": 1, + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2020-11-19 04:05:36.768570", + "modified_by": "Administrator", + "module": "Justworks ERPNext Connector", + "name": "JW Import", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Accounts User", + "share": 1, + "write": 1 + }, + { + "create": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.py b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.py new file mode 100644 index 0000000..4533980 --- /dev/null +++ b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/jw_import.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Studio Infinity and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document +from frappe.utils.csvutils import read_csv_content +from frappe.utils.dateutils import parse_date +import re + +class JWImport(Document): + def process_invoice_file(self): + fcontent = frappe.get_doc('File', + dict(file_url=self.load_from_file)).get_content() + rows = read_csv_content(fcontent) + header = [frappe.scrub(h) for h in rows.pop(0)] + self.set('lines', []) + for row in rows: + rec = self.append('lines', {}) + for fieldname, val in zip(header, row): + if val: + if fieldname[-4:] == 'date': + val = parse_date(val) + elif fieldname == 'amount': + val = re.sub('^[^.,\d]*', '', val) + rec.set(fieldname, val) diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/test_jw_import.py b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/test_jw_import.py new file mode 100644 index 0000000..ab9f309 --- /dev/null +++ b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_import/test_jw_import.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Studio Infinity and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestJWImport(unittest.TestCase): + pass diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/__init__.py b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/jw_invoice_line.json b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/jw_invoice_line.json new file mode 100644 index 0000000..f854faf --- /dev/null +++ b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/jw_invoice_line.json @@ -0,0 +1,199 @@ +{ + "actions": [], + "creation": "2020-11-18 15:01:37.898595", + "description": "One line or summary line of a Justworks Invoice, roughly corresponding to a single ledger entry if recorded.\n", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "invoice_id", + "invoice_date", + "reference", + "reference_doctype", + "reference_doc", + "top_column_break", + "debit_date", + "charge_type", + "charge_subtype", + "account", + "amount", + "status_section", + "data_status", + "status_column_break", + "disposition", + "voucher_section", + "voucher_id", + "voucher_type", + "voucher_pay_date", + "voucher_column_break", + "period_start_date", + "period_end_date", + "department", + "additional_section", + "reference_work_id", + "notes" + ], + "fields": [ + { + "fieldname": "invoice_id", + "fieldtype": "Data", + "label": "Invoice ID", + "read_only": 1 + }, + { + "fieldname": "invoice_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Invoice Date" + }, + { + "fieldname": "reference", + "fieldtype": "Data", + "label": "Reference", + "read_only": 1 + }, + { + "fieldname": "reference_doctype", + "fieldtype": "Link", + "label": "Reference Type", + "options": "DocType" + }, + { + "fieldname": "reference_doc", + "fieldtype": "Dynamic Link", + "in_list_view": 1, + "label": "Reference Doc", + "options": "reference_doctype" + }, + { + "fieldname": "top_column_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "debit_date", + "fieldtype": "Date", + "label": "Debit Date" + }, + { + "fieldname": "charge_type", + "fieldtype": "Data", + "label": "Charge Type", + "read_only": 1 + }, + { + "fieldname": "charge_subtype", + "fieldtype": "Data", + "label": "Charge Subtype", + "read_only": 1 + }, + { + "fieldname": "account", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Account", + "options": "Account" + }, + { + "fieldname": "amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Amount", + "options": "justworks_currency" + }, + { + "fieldname": "status_section", + "fieldtype": "Section Break", + "label": "Status" + }, + { + "columns": 1, + "fieldname": "data_status", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Data", + "options": "OK\nBad Alloc\nNo Account", + "read_only": 1 + }, + { + "fieldname": "status_column_break", + "fieldtype": "Column Break" + }, + { + "columns": 1, + "fieldname": "disposition", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Disposition", + "options": "Journal\nPay Invoice\nPay Expense\nCollection\nIgnore\nDuplicate\nData Missing" + }, + { + "fieldname": "voucher_section", + "fieldtype": "Section Break", + "label": "Justworks Voucher" + }, + { + "fieldname": "voucher_id", + "fieldtype": "Data", + "label": "Voucher ID", + "read_only": 1 + }, + { + "fieldname": "voucher_type", + "fieldtype": "Data", + "label": "Voucher Type" + }, + { + "fieldname": "voucher_pay_date", + "fieldtype": "Date", + "label": "Pay Date" + }, + { + "fieldname": "voucher_column_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "period_start_date", + "fieldtype": "Date", + "label": "Period Start" + }, + { + "fieldname": "period_end_date", + "fieldtype": "Date", + "label": "Period End" + }, + { + "fieldname": "department", + "fieldtype": "Data", + "label": "Department" + }, + { + "fieldname": "additional_section", + "fieldtype": "Section Break", + "label": "Additional Information" + }, + { + "fieldname": "reference_work_id", + "fieldtype": "Data", + "label": "Reference Work ID", + "read_only": 1 + }, + { + "fieldname": "notes", + "fieldtype": "Small Text", + "label": "Notes" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2020-11-18 23:21:36.546404", + "modified_by": "Administrator", + "module": "Justworks ERPNext Connector", + "name": "JW Invoice Line", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/jw_invoice_line.py b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/jw_invoice_line.py new file mode 100644 index 0000000..3e5057c --- /dev/null +++ b/justworks_erpnext/justworks_erpnext_connector/doctype/jw_invoice_line/jw_invoice_line.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Studio Infinity and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class JWInvoiceLine(Document): + pass