Added expense/income to je list and added load as draft check
This commit is contained in:
parent
0ef93e4b36
commit
9a3c705b4e
|
|
@ -798,7 +798,7 @@ VATETaxes.errors = {
|
|||
},
|
||||
|
||||
// Показать сводку результатов
|
||||
showSummary: function(totalOperations, processedCount, errorsCount) {
|
||||
showSummary: function(totalOperations, processedCount, errorsCount, createAsDraft = 0) {
|
||||
let title = '';
|
||||
let indicator = '';
|
||||
let message = '';
|
||||
|
|
@ -807,6 +807,9 @@ VATETaxes.errors = {
|
|||
title = __('Import Completed Successfully');
|
||||
indicator = 'green';
|
||||
message = __('All ') + totalOperations + __(' VAT operations were imported successfully.');
|
||||
if (createAsDraft) {
|
||||
message += ' ' + __('(created as Draft)');
|
||||
}
|
||||
|
||||
frappe.msgprint({
|
||||
title: title,
|
||||
|
|
@ -889,6 +892,13 @@ VATETaxes.import = {
|
|||
options: 'Company',
|
||||
reqd: true,
|
||||
default: frappe.defaults.get_user_default('Company')
|
||||
},
|
||||
{
|
||||
fieldname: 'create_as_draft',
|
||||
fieldtype: 'Check',
|
||||
label: __('Create as Draft'),
|
||||
default: 0,
|
||||
description: __('If checked, Journal Entries will be created in Draft status instead of being submitted automatically')
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Search'),
|
||||
|
|
@ -921,9 +931,10 @@ VATETaxes.import = {
|
|||
|
||||
const fromDate = values.creationDateFrom;
|
||||
const toDate = values.creationDateTo;
|
||||
const createAsDraft = values.create_as_draft || 0;
|
||||
|
||||
d.hide();
|
||||
VATETaxes.import.loadOperations(fromDate, toDate, values.company);
|
||||
VATETaxes.import.loadOperations(fromDate, toDate, values.company, [], 0, createAsDraft);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -932,7 +943,7 @@ VATETaxes.import = {
|
|||
},
|
||||
|
||||
// Загрузить операции с фильтрацией дубликатов
|
||||
loadOperations: function(fromDate, toDate, company, accumulatedOperations = [], offset = 0) {
|
||||
loadOperations: function(fromDate, toDate, company, accumulatedOperations = [], offset = 0, createAsDraft = 0) {
|
||||
VATETaxes.cancelLoading = false;
|
||||
$(document).off('progress-cancel.vat_import');
|
||||
|
||||
|
|
@ -979,7 +990,7 @@ VATETaxes.import = {
|
|||
|
||||
if (hasMore && currentOperations.length > 0) {
|
||||
const newOffset = offset + currentOperations.length;
|
||||
VATETaxes.import.loadOperations(fromDate, toDate, company, allOperations, newOffset);
|
||||
VATETaxes.import.loadOperations(fromDate, toDate, company, allOperations, newOffset, createAsDraft);
|
||||
} else {
|
||||
if (allOperations.length > 0) {
|
||||
frappe.show_alert({
|
||||
|
|
@ -987,7 +998,7 @@ VATETaxes.import = {
|
|||
indicator: 'blue'
|
||||
}, 3);
|
||||
|
||||
VATETaxes.import.filterDuplicates(allOperations, mainToken, company);
|
||||
VATETaxes.import.filterDuplicates(allOperations, mainToken, company, createAsDraft);
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Information'),
|
||||
|
|
@ -1001,7 +1012,7 @@ VATETaxes.import = {
|
|||
__('Your E-Taxes session has expired. Would you like to authenticate now?'),
|
||||
function() {
|
||||
VATETaxes.auth.startProcess(function() {
|
||||
VATETaxes.import.loadOperations(fromDate, toDate, company);
|
||||
VATETaxes.import.loadOperations(fromDate, toDate, company, [], 0, createAsDraft);
|
||||
});
|
||||
},
|
||||
function() {
|
||||
|
|
@ -1039,7 +1050,7 @@ VATETaxes.import = {
|
|||
},
|
||||
|
||||
// Фильтрация дубликатов
|
||||
filterDuplicates: function(allOperations, token, company) {
|
||||
filterDuplicates: function(allOperations, token, company, createAsDraft = 0) {
|
||||
frappe.call({
|
||||
method: 'frappe.client.get_list',
|
||||
args: {
|
||||
|
|
@ -1074,7 +1085,7 @@ VATETaxes.import = {
|
|||
}
|
||||
|
||||
if (filteredOperations.length > 0) {
|
||||
VATETaxes.import.showOperationSelection(filteredOperations, token, company);
|
||||
VATETaxes.import.showOperationSelection(filteredOperations, token, company, createAsDraft);
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Information'),
|
||||
|
|
@ -1094,7 +1105,7 @@ VATETaxes.import = {
|
|||
},
|
||||
error: function(err) {
|
||||
console.error("Error fetching VAT operations:", err);
|
||||
VATETaxes.import.showOperationSelection(allOperations, token, company);
|
||||
VATETaxes.import.showOperationSelection(allOperations, token, company, createAsDraft);
|
||||
frappe.show_alert({
|
||||
message: __('Failed to check for duplicates. Showing all operations.'),
|
||||
indicator: 'orange'
|
||||
|
|
@ -1104,7 +1115,7 @@ VATETaxes.import = {
|
|||
},
|
||||
|
||||
// Показать диалог выбора операций
|
||||
showOperationSelection: function(operations, token, company) {
|
||||
showOperationSelection: function(operations, token, company, createAsDraft = 0) {
|
||||
let operationTable = '<div style="max-height: 500px; overflow-y: auto;"><table class="table table-bordered vat-operations-table" style="width: 100%; table-layout: fixed;">';
|
||||
operationTable += '<thead><tr>' +
|
||||
'<th style="width: 3%;"><input type="checkbox" class="select-all-operations"></th>' +
|
||||
|
|
@ -1198,7 +1209,7 @@ VATETaxes.import = {
|
|||
|
||||
d.hide();
|
||||
VATETaxes.cancelLoading = false;
|
||||
VATETaxes.import.loadSelectedOperations(selectedOperations, token, company);
|
||||
VATETaxes.import.loadSelectedOperations(selectedOperations, token, company, 0, 0, createAsDraft);
|
||||
},
|
||||
secondary_action_label: __('Cancel'),
|
||||
secondary_action: function() {
|
||||
|
|
@ -1226,7 +1237,7 @@ VATETaxes.import = {
|
|||
},
|
||||
|
||||
// Загрузка выбранных операций
|
||||
loadSelectedOperations: function(operations, token, company, processedCount = 0, currentIndex = 0) {
|
||||
loadSelectedOperations: function(operations, token, company, processedCount = 0, currentIndex = 0, createAsDraft = 0) {
|
||||
if (processedCount === 0 && currentIndex === 0) {
|
||||
VATETaxes.loadingErrors = [];
|
||||
window.totalOperationsToProcess = operations.length;
|
||||
|
|
@ -1245,7 +1256,7 @@ VATETaxes.import = {
|
|||
|
||||
// Дополнительная микрозадержка для гарантии
|
||||
setTimeout(function() {
|
||||
VATETaxes.errors.showSummary(totalOperations, processedCount, errorsCount);
|
||||
VATETaxes.errors.showSummary(totalOperations, processedCount, errorsCount, createAsDraft);
|
||||
window.totalOperationsToProcess = null;
|
||||
|
||||
if (cur_list) {
|
||||
|
|
@ -1260,7 +1271,7 @@ VATETaxes.import = {
|
|||
if (VATETaxes.cancelLoading) {
|
||||
operations = [];
|
||||
frappe.hide_progress();
|
||||
VATETaxes.import.loadSelectedOperations(operations, token, company, processedCount, currentIndex);
|
||||
VATETaxes.import.loadSelectedOperations(operations, token, company, processedCount, currentIndex, createAsDraft);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1287,11 +1298,12 @@ VATETaxes.import = {
|
|||
method: 'invoice_az.vat_api.import_vat_operations',
|
||||
args: {
|
||||
'operations_data': JSON.stringify([operation]),
|
||||
'company': company
|
||||
'company': company,
|
||||
'create_as_draft': createAsDraft
|
||||
},
|
||||
callback: function(r) {
|
||||
VATETaxes.import._handleImportResult(r, operation,
|
||||
operations, token, company, processedCount, currentIndex, isLastOperation);
|
||||
operations, token, company, processedCount, currentIndex, isLastOperation, createAsDraft);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
const errorMessage = 'Network error during import: ' + (error || 'Unknown network error');
|
||||
|
|
@ -1300,13 +1312,13 @@ VATETaxes.import = {
|
|||
xhr_response: xhr.responseText
|
||||
});
|
||||
|
||||
VATETaxes.import._continueOrFinish(operations, token, company, processedCount, currentIndex, isLastOperation);
|
||||
VATETaxes.import._continueOrFinish(operations, token, company, processedCount, currentIndex, isLastOperation, createAsDraft);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Обработка результата импорта
|
||||
_handleImportResult: function(importR, operation, operations, token, company, processedCount, currentIndex, isLastOperation) {
|
||||
_handleImportResult: function(importR, operation, operations, token, company, processedCount, currentIndex, isLastOperation, createAsDraft = 0) {
|
||||
if (importR.message && importR.message.success) {
|
||||
if (importR.message.imported > 0) {
|
||||
// НЕ показываем индивидуальные алерты во время массового импорта
|
||||
|
|
@ -1318,19 +1330,19 @@ VATETaxes.import = {
|
|||
VATETaxes.errors.add(operation, error.error_type || 'Import Error', error.message, error);
|
||||
}
|
||||
|
||||
VATETaxes.import._continueOrFinish(operations, token, company, processedCount, currentIndex, isLastOperation);
|
||||
VATETaxes.import._continueOrFinish(operations, token, company, processedCount, currentIndex, isLastOperation, createAsDraft);
|
||||
} else {
|
||||
const errorMessage = importR.message ? importR.message.message : 'Unknown import error';
|
||||
VATETaxes.errors.add(operation, 'Import Error', errorMessage, {
|
||||
server_response: importR.message
|
||||
});
|
||||
|
||||
VATETaxes.import._continueOrFinish(operations, token, company, processedCount, currentIndex, isLastOperation);
|
||||
VATETaxes.import._continueOrFinish(operations, token, company, processedCount, currentIndex, isLastOperation, createAsDraft);
|
||||
}
|
||||
},
|
||||
|
||||
// Продолжить или завершить обработку
|
||||
_continueOrFinish: function(operations, token, company, processedCount, currentIndex, isLastOperation) {
|
||||
_continueOrFinish: function(operations, token, company, processedCount, currentIndex, isLastOperation, createAsDraft = 0) {
|
||||
if (isLastOperation) {
|
||||
$(document).off('progress-cancel.loading_operations');
|
||||
|
||||
|
|
@ -1344,7 +1356,7 @@ VATETaxes.import = {
|
|||
|
||||
// Дополнительная микрозадержка для гарантии
|
||||
setTimeout(function() {
|
||||
VATETaxes.errors.showSummary(totalToProcess, processedCount, errorsCount);
|
||||
VATETaxes.errors.showSummary(totalToProcess, processedCount, errorsCount, createAsDraft);
|
||||
|
||||
if (cur_list) {
|
||||
cur_list.refresh();
|
||||
|
|
@ -1360,7 +1372,7 @@ VATETaxes.import = {
|
|||
frappe.hide_progress();
|
||||
}
|
||||
|
||||
VATETaxes.import.loadSelectedOperations(operations, token, company, processedCount, currentIndex);
|
||||
VATETaxes.import.loadSelectedOperations(operations, token, company, processedCount, currentIndex, createAsDraft);
|
||||
}, VATETaxes.PROGRESS_UPDATE_DELAY);
|
||||
}
|
||||
};
|
||||
|
|
@ -1369,7 +1381,7 @@ VATETaxes.import = {
|
|||
|
||||
// Journal Entry List
|
||||
frappe.listview_settings['Journal Entry'] = {
|
||||
add_fields: ['posting_date', 'voucher_type', 'total_debit', 'total_credit', 'docstatus'],
|
||||
add_fields: ['posting_date', 'voucher_type', 'total_debit', 'total_credit', 'docstatus', 'expense_income_type'],
|
||||
|
||||
get_indicator: function(doc) {
|
||||
if (doc.docstatus == 1) {
|
||||
|
|
@ -1381,6 +1393,17 @@ frappe.listview_settings['Journal Entry'] = {
|
|||
}
|
||||
},
|
||||
|
||||
formatters: {
|
||||
expense_income_type: function(value) {
|
||||
if (value === 'Income') {
|
||||
return '<span class="indicator-pill green">' + value + '</span>';
|
||||
} else if (value === 'Expense') {
|
||||
return '<span class="indicator-pill red">' + value + '</span>';
|
||||
}
|
||||
return value || '';
|
||||
}
|
||||
},
|
||||
|
||||
onload: function(listview) {
|
||||
listview.page.add_menu_item(__('Import VAT Operations from E-Taxes'), function() {
|
||||
VATETaxes.import.showDialog();
|
||||
|
|
|
|||
|
|
@ -349,13 +349,14 @@ def get_accounts_for_operation_type(operation_type, company, expense_income_type
|
|||
return (None, None)
|
||||
|
||||
|
||||
def create_journal_entry_from_vat_operation(operation_data, company):
|
||||
def create_journal_entry_from_vat_operation(operation_data, company, create_as_draft=0):
|
||||
"""
|
||||
Создание Journal Entry из VAT операции
|
||||
|
||||
Args:
|
||||
operation_data (dict): Данные операции из API
|
||||
company (str): Название компании
|
||||
create_as_draft (int): 1 для создания в Draft, 0 для auto-submit
|
||||
|
||||
Returns:
|
||||
dict: Результат создания с именем JE или ошибкой
|
||||
|
|
@ -453,6 +454,7 @@ def create_journal_entry_from_vat_operation(operation_data, company):
|
|||
je.company = company
|
||||
je.voucher_type = 'Journal Entry'
|
||||
je.user_remark = f"VAT Operation: {operation_data.get('explanation', '')}"
|
||||
je.expense_income_type = expense_income_type
|
||||
|
||||
# Строка 1: Дебет
|
||||
debit_entry = {
|
||||
|
|
@ -482,24 +484,30 @@ def create_journal_entry_from_vat_operation(operation_data, company):
|
|||
|
||||
je.append('accounts', credit_entry)
|
||||
|
||||
# Сохраняем и submit
|
||||
# Сохраняем и submit (если не draft режим)
|
||||
je.insert()
|
||||
je.submit()
|
||||
|
||||
if not create_as_draft:
|
||||
je.submit()
|
||||
else:
|
||||
frappe.logger().info(f"Journal Entry {je.name} created as Draft (not submitted)")
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'journal_entry': je.name,
|
||||
'posting_date': str(posting_date)
|
||||
'posting_date': str(posting_date),
|
||||
'status': 'Draft' if create_as_draft else 'Submitted'
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
frappe.log_error(f"Error creating JE from VAT operation: {str(e)}\n{frappe.get_traceback()}",
|
||||
error_context = "creating draft" if create_as_draft else "creating and submitting"
|
||||
frappe.log_error(f"Error {error_context} JE from VAT operation: {str(e)}\n{frappe.get_traceback()}",
|
||||
"VAT JE Creation Error")
|
||||
return {
|
||||
'success': False,
|
||||
'message': f'Error creating Journal Entry: {str(e)}'
|
||||
'message': f'Error {error_context} Journal Entry: {str(e)}'
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -579,13 +587,14 @@ def create_vat_operation_record(operation_data, journal_entry_name=None, status=
|
|||
|
||||
|
||||
@frappe.whitelist()
|
||||
def import_vat_operations(operations_data, company=None):
|
||||
def import_vat_operations(operations_data, company=None, create_as_draft=0):
|
||||
"""
|
||||
Импорт VAT операций и создание Journal Entries
|
||||
|
||||
Args:
|
||||
operations_data (str/list): JSON строка или список операций
|
||||
company (str): Название компании (опционально)
|
||||
create_as_draft (int): 1 для создания в Draft, 0 для auto-submit
|
||||
|
||||
Returns:
|
||||
dict: Результат импорта с статистикой
|
||||
|
|
@ -597,6 +606,12 @@ def import_vat_operations(operations_data, company=None):
|
|||
if isinstance(operations_data, str):
|
||||
operations_data = json.loads(operations_data)
|
||||
|
||||
# Обработка create_as_draft параметра
|
||||
try:
|
||||
create_as_draft = int(create_as_draft)
|
||||
except (ValueError, TypeError):
|
||||
create_as_draft = 0
|
||||
|
||||
# Получаем компанию
|
||||
if not company:
|
||||
company = frappe.defaults.get_user_default('Company')
|
||||
|
|
@ -628,7 +643,7 @@ def import_vat_operations(operations_data, company=None):
|
|||
continue
|
||||
|
||||
# Создаем Journal Entry
|
||||
je_result = create_journal_entry_from_vat_operation(operation, company)
|
||||
je_result = create_journal_entry_from_vat_operation(operation, company, create_as_draft)
|
||||
|
||||
if je_result.get('success'):
|
||||
# Создаем запись отслеживания
|
||||
|
|
|
|||
Loading…
Reference in New Issue