chore(sales-invoice): remove Won/Lost checkboxes
Drop the conditional Won/Lost Custom Fields and their JS/Python plumbing — they should never be shown again. Adds a post-migrate patch to delete the existing Custom Field records (and any stray Property Setters) from the DB. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1a6bd5649b
commit
e81f4bc8e8
|
|
@ -3,36 +3,6 @@ import json
|
|||
from frappe.utils import flt
|
||||
|
||||
|
||||
def validate_won_lost_fields(doc, method=None):
|
||||
"""
|
||||
Ensure that exactly one of won/lost checkboxes is always selected for gambling companies
|
||||
Automatically fixes the issue instead of throwing an error
|
||||
"""
|
||||
if doc.doctype != "Sales Invoice":
|
||||
return
|
||||
|
||||
# Check if this is a gambling company
|
||||
allowed_activities = ["92000", "9200003", "9200004", "9200001", "9200002", "9200005"]
|
||||
company_main_activity = doc.get('company_main_activity')
|
||||
|
||||
if not company_main_activity or company_main_activity not in allowed_activities:
|
||||
# Not a gambling company - skip validation
|
||||
return
|
||||
|
||||
# Check if both fields exist
|
||||
if not hasattr(doc, 'won') or not hasattr(doc, 'lost'):
|
||||
return
|
||||
|
||||
# Для gambling компаний - автоматически исправляем ситуацию
|
||||
if not doc.won and not doc.lost:
|
||||
# Если обе выключены - включаем won по умолчанию
|
||||
doc.won = 1
|
||||
doc.lost = 0
|
||||
elif doc.won and doc.lost:
|
||||
# Если обе включены - оставляем только won
|
||||
doc.lost = 0
|
||||
|
||||
|
||||
def calculate_tax_free_amounts(doc, method=None):
|
||||
"""
|
||||
Calculate tax free amounts for Sales Invoice
|
||||
|
|
|
|||
|
|
@ -723,27 +723,6 @@ def create_custom_fields():
|
|||
insert_after='act_type',
|
||||
depends_on='eval:doc.purchase_type && doc.act_type == "Import"'
|
||||
),
|
||||
# Won and Lost checkboxes - в одну строку
|
||||
dict(
|
||||
fieldname='won',
|
||||
label='Won',
|
||||
fieldtype='Check',
|
||||
insert_after='section_break_42',
|
||||
depends_on='eval:doc.company_main_activity && ["92000", "9200003", "9200004", "9200001", "9200002", "9200005"].includes(doc.company_main_activity)',
|
||||
default=1,
|
||||
allow_on_submit=1,
|
||||
mandatory_depends_on='eval:doc.company_main_activity && ["92000", "9200003", "9200004", "9200001", "9200002", "9200005"].includes(doc.company_main_activity)'
|
||||
),
|
||||
dict(
|
||||
fieldname='lost',
|
||||
label='Lost',
|
||||
fieldtype='Check',
|
||||
insert_after='won',
|
||||
depends_on='eval:doc.company_main_activity && ["92000", "9200003", "9200004", "9200001", "9200002", "9200005"].includes(doc.company_main_activity)',
|
||||
default=0,
|
||||
allow_on_submit=1,
|
||||
mandatory_depends_on='eval:doc.company_main_activity && ["92000", "9200003", "9200004", "9200001", "9200002", "9200005"].includes(doc.company_main_activity)'
|
||||
),
|
||||
# New comments section after time_sheet_list
|
||||
dict(
|
||||
fieldname='comments_section',
|
||||
|
|
|
|||
|
|
@ -55,12 +55,8 @@ doc_events = {
|
|||
},
|
||||
"Sales Invoice": {
|
||||
"validate": [
|
||||
"jey_erp.custom.sales_invoice.validate_won_lost_fields",
|
||||
"jey_erp.custom.sales_invoice.calculate_tax_free_amounts",
|
||||
],
|
||||
"before_save": [
|
||||
"jey_erp.custom.sales_invoice.validate_won_lost_fields",
|
||||
],
|
||||
"on_update": [
|
||||
"jey_erp.custom.sales_invoice.calculate_tax_free_amounts",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -8,4 +8,5 @@ jey_erp.patches.fix_employee_columns_as_text
|
|||
# Patches added in this section will be executed after doctypes are migrated
|
||||
jey_erp.patches.create_asset_categories_post_migration
|
||||
jey_erp.patches.remove_old_won_lost_fields
|
||||
jey_erp.patches.remove_won_lost_breaks
|
||||
jey_erp.patches.remove_won_lost_breaks
|
||||
jey_erp.patches.remove_won_lost_checkboxes
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
"""Permanently drop the Won/Lost checkbox Custom Fields from Sales Invoice."""
|
||||
|
||||
fieldnames = ["won", "lost"]
|
||||
|
||||
for fieldname in fieldnames:
|
||||
name = frappe.db.get_value(
|
||||
"Custom Field", {"dt": "Sales Invoice", "fieldname": fieldname}, "name"
|
||||
)
|
||||
if not name:
|
||||
continue
|
||||
try:
|
||||
frappe.delete_doc("Custom Field", name, ignore_permissions=True, force=True)
|
||||
print(f"Deleted Custom Field: Sales Invoice.{fieldname}")
|
||||
except Exception as e:
|
||||
print(f"Failed to delete Sales Invoice.{fieldname}: {e}")
|
||||
|
||||
# Drop any Property Setters that targeted these fields.
|
||||
frappe.db.delete(
|
||||
"Property Setter",
|
||||
{"doc_type": "Sales Invoice", "field_name": ("in", fieldnames)},
|
||||
)
|
||||
|
||||
frappe.clear_cache(doctype="Sales Invoice")
|
||||
frappe.db.commit()
|
||||
|
|
@ -1,81 +1,15 @@
|
|||
// Запускаем логику калькулятора НДС для Sales Invoice
|
||||
jey_erp.vat_calculator.init('Sales Invoice');
|
||||
|
||||
// Простая логика для чекбоксов Won/Lost и Seller/Organizer
|
||||
// Логика для чекбоксов Seller/Organizer
|
||||
frappe.ui.form.on('Sales Invoice', {
|
||||
refresh: function(frm) {
|
||||
// Убедимся что одна из галочек Won/Lost выбрана (для gambling компаний)
|
||||
if (is_gambling_company(frm)) {
|
||||
if (!frm.doc.won && !frm.doc.lost) {
|
||||
frm.set_value('won', 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Убедимся что одна из галочек Seller/Organizer выбрана (если поля видимы)
|
||||
if (should_show_seller_organizer(frm)) {
|
||||
if (!frm.doc.seller && !frm.doc.organizer) {
|
||||
frm.set_value('organizer', 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Применяем CSS для отображения Won и Lost в одну строку близко друг к другу
|
||||
apply_inline_checkbox_style(frm);
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
// Применяем стиль при загрузке формы
|
||||
apply_inline_checkbox_style(frm);
|
||||
},
|
||||
|
||||
// Обработчики для Won/Lost - гарантируем что всегда одна галочка включена
|
||||
won: function(frm) {
|
||||
if (!is_gambling_company(frm)) return;
|
||||
|
||||
if (frm.doc.won) {
|
||||
// Включили won - выключаем lost
|
||||
if (frm.doc.lost) {
|
||||
frm.set_value('lost', 0);
|
||||
}
|
||||
} else {
|
||||
// Выключили won - автоматически включаем lost
|
||||
frm.set_value('lost', 1);
|
||||
}
|
||||
},
|
||||
|
||||
lost: function(frm) {
|
||||
if (!is_gambling_company(frm)) return;
|
||||
|
||||
if (frm.doc.lost) {
|
||||
// Включили lost - выключаем won
|
||||
if (frm.doc.won) {
|
||||
frm.set_value('won', 0);
|
||||
}
|
||||
} else {
|
||||
// Выключили lost - автоматически включаем won
|
||||
frm.set_value('won', 1);
|
||||
}
|
||||
},
|
||||
|
||||
before_save: function(frm) {
|
||||
// Перед сохранением убеждаемся что одна галочка включена
|
||||
if (is_gambling_company(frm)) {
|
||||
if (!frm.doc.won && !frm.doc.lost) {
|
||||
frm.set_value('won', 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
validate: function(frm) {
|
||||
// Валидация для gambling компаний - автоматически исправляем
|
||||
if (is_gambling_company(frm)) {
|
||||
if (!frm.doc.won && !frm.doc.lost) {
|
||||
// Если обе выключены, включаем won
|
||||
frm.set_value('won', 1);
|
||||
} else if (frm.doc.won && frm.doc.lost) {
|
||||
// Если обе включены, оставляем только won
|
||||
frm.set_value('lost', 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Обработчики для Seller/Organizer
|
||||
|
|
@ -112,43 +46,13 @@ frappe.ui.form.on('Sales Invoice', {
|
|||
}
|
||||
});
|
||||
|
||||
// Функция проверки, является ли компания gambling компанией
|
||||
function is_gambling_company(frm) {
|
||||
// Функция проверки, должны ли быть видимы поля Seller/Organizer
|
||||
function should_show_seller_organizer(frm) {
|
||||
const allowed_activities = ["92000", "9200003", "9200004", "9200001", "9200002", "9200005"];
|
||||
return frm.doc.company_main_activity &&
|
||||
allowed_activities.includes(frm.doc.company_main_activity);
|
||||
}
|
||||
|
||||
// Функция проверки, должны ли быть видимы поля Seller/Organizer (то же самое условие)
|
||||
function should_show_seller_organizer(frm) {
|
||||
return is_gambling_company(frm);
|
||||
}
|
||||
|
||||
// Функция для применения CSS стилей чтобы чекбоксы были в одну строку
|
||||
function apply_inline_checkbox_style(frm) {
|
||||
// Добавляем CSS если еще не добавлен
|
||||
if (!document.getElementById('won-lost-inline-style')) {
|
||||
const style = document.createElement('style');
|
||||
style.id = 'won-lost-inline-style';
|
||||
style.textContent = `
|
||||
/* Делаем Won и Lost в одну строку */
|
||||
[data-fieldname="won"],
|
||||
[data-fieldname="lost"] {
|
||||
display: inline-block !important;
|
||||
width: auto !important;
|
||||
margin-right: 30px !important;
|
||||
vertical-align: top !important;
|
||||
}
|
||||
|
||||
/* Убираем перенос строки после Won */
|
||||
[data-fieldname="won"] + [data-fieldname="lost"] {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
}
|
||||
|
||||
// Функция синхронизации фактических сумм НДС из items в taxes
|
||||
function sync_vat_amounts_to_taxes(frm) {
|
||||
if (!frm.doc.items || !frm.doc.taxes || frm.doc.items.length === 0) return;
|
||||
|
|
@ -209,4 +113,4 @@ frappe.ui.form.on('Sales Invoice Item', {
|
|||
sync_vat_amounts_to_taxes(frm);
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue