Merge branch 'develop' into project-naming-series-patch
This commit is contained in:
commit
465974cff0
@ -21,6 +21,7 @@
|
||||
"book_asset_depreciation_entry_automatically",
|
||||
"add_taxes_from_item_tax_template",
|
||||
"automatically_fetch_payment_terms",
|
||||
"delete_linked_ledger_entries",
|
||||
"deferred_accounting_settings_section",
|
||||
"automatically_process_deferred_accounting_entry",
|
||||
"book_deferred_entries_based_on",
|
||||
@ -219,6 +220,12 @@
|
||||
"fieldtype": "Select",
|
||||
"label": "Book Deferred Entries Based On",
|
||||
"options": "Days\nMonths"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "delete_linked_ledger_entries",
|
||||
"fieldtype": "Check",
|
||||
"label": "Delete Accounting and Stock Ledger Entries on deletion of Transaction"
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
@ -226,7 +233,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-13 11:32:52.268826",
|
||||
"modified": "2021-01-05 13:04:00.118892",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
@ -254,4 +261,4 @@
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
@ -34,6 +34,9 @@ def valdiate_taxes_and_charges_template(doc):
|
||||
|
||||
validate_disabled(doc)
|
||||
|
||||
# Validate with existing taxes and charges template for unique tax category
|
||||
validate_for_tax_category(doc)
|
||||
|
||||
for tax in doc.get("taxes"):
|
||||
validate_taxes_and_charges(tax)
|
||||
validate_inclusive_tax(tax, doc)
|
||||
@ -41,3 +44,7 @@ def valdiate_taxes_and_charges_template(doc):
|
||||
def validate_disabled(doc):
|
||||
if doc.is_default and doc.disabled:
|
||||
frappe.throw(_("Disabled template must not be default template"))
|
||||
|
||||
def validate_for_tax_category(doc):
|
||||
if frappe.db.exists(doc.doctype, {"company": doc.company, "tax_category": doc.tax_category, "disabled": 0}):
|
||||
frappe.throw(_("A template with tax category {0} already exists. Only one template is allowed with each tax category").format(frappe.bold(doc.tax_category)))
|
||||
|
@ -152,7 +152,7 @@
|
||||
<td class="text-right">{{ frappe.utils.fmt_money(value_details.CesVal, None, "INR") }}</td>
|
||||
<td class="text-right">{{ frappe.utils.fmt_money(0, None, "INR") }}</td>
|
||||
<td class="text-right">{{ frappe.utils.fmt_money(value_details.Discount, None, "INR") }}</td>
|
||||
<td class="text-right">{{ frappe.utils.fmt_money(0, None, "INR") }}</td>
|
||||
<td class="text-right">{{ frappe.utils.fmt_money(value_details.OthChrg, None, "INR") }}</td>
|
||||
<td class="text-right">{{ frappe.utils.fmt_money(value_details.RndOffAmt, None, "INR") }}</td>
|
||||
<td class="text-right">{{ frappe.utils.fmt_money(value_details.TotInvVal, None, "INR") }}</td>
|
||||
</tr>
|
||||
|
@ -381,7 +381,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
material_request_type: "Purchase",
|
||||
docstatus: 1,
|
||||
status: ["!=", "Stopped"],
|
||||
per_ordered: ["<", 99.99],
|
||||
per_ordered: ["<", 100],
|
||||
company: me.frm.doc.company
|
||||
}
|
||||
})
|
||||
|
@ -224,7 +224,7 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
||||
material_request_type: "Purchase",
|
||||
docstatus: 1,
|
||||
status: ["!=", "Stopped"],
|
||||
per_ordered: ["<", 99.99],
|
||||
per_ordered: ["<", 100],
|
||||
company: me.frm.doc.company
|
||||
}
|
||||
})
|
||||
@ -280,7 +280,7 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
||||
material_request_type: "Purchase",
|
||||
docstatus: 1,
|
||||
status: ["!=", "Stopped"],
|
||||
per_ordered: ["<", 99.99]
|
||||
per_ordered: ["<", 100]
|
||||
}
|
||||
});
|
||||
dialog.hide();
|
||||
|
@ -44,7 +44,7 @@ erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.ext
|
||||
material_request_type: "Purchase",
|
||||
docstatus: 1,
|
||||
status: ["!=", "Stopped"],
|
||||
per_ordered: ["<", 99.99],
|
||||
per_ordered: ["<", 100],
|
||||
company: me.frm.doc.company
|
||||
}
|
||||
})
|
||||
|
@ -118,6 +118,12 @@ class AccountsController(TransactionBase):
|
||||
|
||||
def before_cancel(self):
|
||||
validate_einvoice_fields(self)
|
||||
|
||||
def on_trash(self):
|
||||
# delete sl and gl entries on deletion of transaction
|
||||
if frappe.db.get_single_value('Accounts Settings', 'delete_linked_ledger_entries'):
|
||||
frappe.db.sql("delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name))
|
||||
frappe.db.sql("delete from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name))
|
||||
|
||||
def validate_deferred_start_and_end_date(self):
|
||||
for d in self.items:
|
||||
|
@ -416,9 +416,6 @@ regional_overrides = {
|
||||
'Italy': {
|
||||
'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.italy.utils.update_itemised_tax_data',
|
||||
'erpnext.controllers.accounts_controller.validate_regional': 'erpnext.regional.italy.utils.sales_invoice_validate',
|
||||
},
|
||||
'Germany': {
|
||||
'erpnext.controllers.accounts_controller.validate_regional': 'erpnext.regional.germany.accounts_controller.validate_regional',
|
||||
}
|
||||
}
|
||||
user_privacy_documents = [
|
||||
|
@ -88,7 +88,7 @@ def get_events(start, end, filters=None):
|
||||
|
||||
def add_assignments(events, start, end, conditions=None):
|
||||
query = """select name, start_date, end_date, employee_name,
|
||||
employee, docstatus
|
||||
employee, docstatus, shift_type
|
||||
from `tabShift Assignment` where
|
||||
start_date >= %(start_date)s
|
||||
or end_date <= %(end_date)s
|
||||
@ -97,18 +97,40 @@ def add_assignments(events, start, end, conditions=None):
|
||||
if conditions:
|
||||
query += conditions
|
||||
|
||||
for d in frappe.db.sql(query, {"start_date":start, "end_date":end}, as_dict=True):
|
||||
e = {
|
||||
"name": d.name,
|
||||
"doctype": "Shift Assignment",
|
||||
"start_date": d.start_date,
|
||||
"end_date": d.end_date if d.end_date else nowdate(),
|
||||
"title": cstr(d.employee_name) + ": "+ \
|
||||
cstr(d.shift_type),
|
||||
"docstatus": d.docstatus
|
||||
}
|
||||
if e not in events:
|
||||
events.append(e)
|
||||
records = frappe.db.sql(query, {"start_date":start, "end_date":end}, as_dict=True)
|
||||
shift_timing_map = get_shift_type_timing([d.shift_type for d in records])
|
||||
|
||||
for d in records:
|
||||
daily_event_start = d.start_date
|
||||
daily_event_end = d.end_date if d.end_date else getdate()
|
||||
delta = timedelta(days=1)
|
||||
while daily_event_start <= daily_event_end:
|
||||
start_timing = frappe.utils.get_datetime(daily_event_start)+ shift_timing_map[d.shift_type]['start_time']
|
||||
end_timing = frappe.utils.get_datetime(daily_event_start)+ shift_timing_map[d.shift_type]['end_time']
|
||||
daily_event_start += delta
|
||||
e = {
|
||||
"name": d.name,
|
||||
"doctype": "Shift Assignment",
|
||||
"start_date": start_timing,
|
||||
"end_date": end_timing,
|
||||
"title": cstr(d.employee_name) + ": "+ \
|
||||
cstr(d.shift_type),
|
||||
"docstatus": d.docstatus,
|
||||
"allDay": 0
|
||||
}
|
||||
if e not in events:
|
||||
events.append(e)
|
||||
|
||||
return events
|
||||
|
||||
def get_shift_type_timing(shift_types):
|
||||
shift_timing_map = {}
|
||||
data = frappe.get_all("Shift Type", filters = {"name": ("IN", shift_types)}, fields = ['name', 'start_time', 'end_time'])
|
||||
|
||||
for d in data:
|
||||
shift_timing_map[d.name] = d
|
||||
|
||||
return shift_timing_map
|
||||
|
||||
|
||||
def get_employee_shift(employee, for_date=nowdate(), consider_default_shift=False, next_shift_direction=None):
|
||||
|
@ -6,14 +6,8 @@ frappe.views.calendar["Shift Assignment"] = {
|
||||
"start": "start_date",
|
||||
"end": "end_date",
|
||||
"id": "name",
|
||||
"docstatus": 1
|
||||
},
|
||||
options: {
|
||||
header: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: 'month'
|
||||
}
|
||||
"docstatus": 1,
|
||||
"allDay": "allDay",
|
||||
},
|
||||
get_events_method: "erpnext.hr.doctype.shift_assignment.shift_assignment.get_events"
|
||||
}
|
@ -43,22 +43,24 @@ def get_data(filters):
|
||||
currency = erpnext.get_company_currency(filters.get('company'))
|
||||
|
||||
for key, qty in iteritems(pledge_values):
|
||||
row = {}
|
||||
current_value = flt(qty * loan_security_details.get(key[1], {}).get('latest_price', 0))
|
||||
valid_upto = loan_security_details.get(key[1], {}).get('valid_upto')
|
||||
if qty:
|
||||
row = {}
|
||||
current_value = flt(qty * loan_security_details.get(key[1], {}).get('latest_price', 0))
|
||||
valid_upto = loan_security_details.get(key[1], {}).get('valid_upto')
|
||||
|
||||
row.update(loan_security_details.get(key[1]))
|
||||
row.update({
|
||||
'applicant_type': applicant_type_map.get(key[0]),
|
||||
'applicant_name': key[0],
|
||||
'total_qty': qty,
|
||||
'current_value': current_value,
|
||||
'price_valid_upto': valid_upto,
|
||||
'portfolio_percent': flt(current_value * 100 / total_value_map.get(key[0]), 2),
|
||||
'currency': currency
|
||||
})
|
||||
row.update(loan_security_details.get(key[1]))
|
||||
row.update({
|
||||
'applicant_type': applicant_type_map.get(key[0]),
|
||||
'applicant_name': key[0],
|
||||
'total_qty': qty,
|
||||
'current_value': current_value,
|
||||
'price_valid_upto': valid_upto,
|
||||
'portfolio_percent': flt(current_value * 100 / total_value_map.get(key[0]), 2) if total_value_map.get(key[0]) \
|
||||
else 0.0,
|
||||
'currency': currency
|
||||
})
|
||||
|
||||
data.append(row)
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
|
||||
|
@ -40,21 +40,22 @@ def get_data(filters):
|
||||
currency = erpnext.get_company_currency(filters.get('company'))
|
||||
|
||||
for security, value in iteritems(current_pledges):
|
||||
row = {}
|
||||
current_value = flt(value.get('qty', 0) * loan_security_details.get(security, {}).get('latest_price', 0))
|
||||
valid_upto = loan_security_details.get(security, {}).get('valid_upto')
|
||||
if value.get('qty'):
|
||||
row = {}
|
||||
current_value = flt(value.get('qty', 0) * loan_security_details.get(security, {}).get('latest_price', 0))
|
||||
valid_upto = loan_security_details.get(security, {}).get('valid_upto')
|
||||
|
||||
row.update(loan_security_details.get(security))
|
||||
row.update({
|
||||
'total_qty': value.get('qty'),
|
||||
'current_value': current_value,
|
||||
'price_valid_upto': valid_upto,
|
||||
'portfolio_percent': flt(current_value * 100 / total_portfolio_value, 2),
|
||||
'pledged_applicant_count': value.get('applicant_count'),
|
||||
'currency': currency
|
||||
})
|
||||
row.update(loan_security_details.get(security))
|
||||
row.update({
|
||||
'total_qty': value.get('qty'),
|
||||
'current_value': current_value,
|
||||
'price_valid_upto': valid_upto,
|
||||
'portfolio_percent': flt(current_value * 100 / total_portfolio_value, 2),
|
||||
'pledged_applicant_count': value.get('applicant_count'),
|
||||
'currency': currency
|
||||
})
|
||||
|
||||
data.append(row)
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
|
||||
|
@ -53,8 +53,7 @@ frappe.ui.form.on('Additional Salary', {
|
||||
if (!frm.doc.company) return;
|
||||
frm.set_query("salary_component", function() {
|
||||
return {
|
||||
query: "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "earning", company: frm.doc.company}
|
||||
filters: {type: ["in", ["earning", "deduction"]], company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
@ -10,15 +10,7 @@ frappe.ui.form.on('Employee Incentive', {
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (!frm.doc.company) return;
|
||||
frm.set_query("salary_component", function() {
|
||||
return {
|
||||
query: "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "earning", company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
|
||||
frm.trigger('set_earning_component');
|
||||
},
|
||||
|
||||
employee: function(frm) {
|
||||
@ -45,11 +37,21 @@ frappe.ui.form.on('Employee Incentive', {
|
||||
callback: function(data) {
|
||||
if (data.message) {
|
||||
frm.set_value("company", data.message.company);
|
||||
frm.trigger('set_earning_component');
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
set_earning_component: function(frm) {
|
||||
if (!frm.doc.company) return;
|
||||
frm.set_query("salary_component", function() {
|
||||
return {
|
||||
filters: {type: "earning", company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
get_employee_currency: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment.get_employee_currency",
|
||||
|
@ -58,13 +58,11 @@ frappe.ui.form.on('Salary Structure', {
|
||||
if(!frm.doc.company) return;
|
||||
frm.set_query("salary_component", "earnings", function() {
|
||||
return {
|
||||
query : "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "earning", company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
frm.set_query("salary_component", "deductions", function() {
|
||||
return {
|
||||
query : "erpnext.payroll.doctype.salary_structure.salary_structure.get_earning_deduction_components",
|
||||
filters: {type: "deduction", company: frm.doc.company}
|
||||
};
|
||||
});
|
||||
|
@ -207,22 +207,3 @@ def get_employees(salary_structure):
|
||||
|
||||
return list(set([d.employee for d in employees]))
|
||||
|
||||
@frappe.whitelist()
|
||||
@frappe.validate_and_sanitize_search_inputs
|
||||
def get_earning_deduction_components(doctype, txt, searchfield, start, page_len, filters):
|
||||
if len(filters) < 2:
|
||||
return {}
|
||||
|
||||
return frappe.db.sql("""
|
||||
select t1.salary_component
|
||||
from `tabSalary Component` t1, `tabSalary Component Account` t2
|
||||
where (t1.name = t2.parent
|
||||
and t1.type = %(type)s
|
||||
and t2.company = %(company)s)
|
||||
or (t1.type = %(type)s
|
||||
and t1.statistical_component = 1)
|
||||
order by salary_component
|
||||
""",{
|
||||
"type": filters['type'],
|
||||
"company": filters['company']
|
||||
})
|
||||
|
@ -195,6 +195,10 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
||||
this._super(doc, cdt, cdn);
|
||||
},
|
||||
|
||||
batch_no: function(doc, cdt, cdn) {
|
||||
this._super(doc, cdt, cdn);
|
||||
},
|
||||
|
||||
received_qty: function(doc, cdt, cdn) {
|
||||
this.calculate_accepted_qty(doc, cdt, cdn)
|
||||
},
|
||||
|
@ -589,11 +589,21 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
return frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"])
|
||||
.then((r) => {
|
||||
if (r.message &&
|
||||
(r.message.has_batch_no || r.message.has_serial_no)) {
|
||||
(r.message.has_batch_no || r.message.has_serial_no)) {
|
||||
frappe.flags.hide_serial_batch_dialog = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
// check if batch serial selector is disabled or not
|
||||
if (show_batch_dialog && !frappe.flags.hide_serial_batch_dialog)
|
||||
return frappe.db.get_single_value('Stock Settings', 'disable_serial_no_and_batch_selector')
|
||||
.then((value) => {
|
||||
if (value) {
|
||||
frappe.flags.hide_serial_batch_dialog = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
if(show_batch_dialog && !frappe.flags.hide_serial_batch_dialog) {
|
||||
var d = locals[cdt][cdn];
|
||||
@ -1099,6 +1109,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
},
|
||||
|
||||
batch_no: function(doc, cdt, cdn) {
|
||||
let item = frappe.get_doc(cdt, cdn);
|
||||
this.apply_price_list(item, true);
|
||||
},
|
||||
|
||||
toggle_conversion_factor: function(item) {
|
||||
// toggle read only property for conversion factor field if the uom and stock uom are same
|
||||
if(this.frm.get_field('items').grid.fields_map.conversion_factor) {
|
||||
@ -1403,6 +1418,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
"pricing_rules": d.pricing_rules,
|
||||
"warehouse": d.warehouse,
|
||||
"serial_no": d.serial_no,
|
||||
"batch_no": d.batch_no,
|
||||
"price_list_rate": d.price_list_rate,
|
||||
"conversion_factor": d.conversion_factor || 1.0
|
||||
});
|
||||
|
@ -7,13 +7,14 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"client",
|
||||
"account_number_length",
|
||||
"column_break_2",
|
||||
"client_number",
|
||||
"section_break_4",
|
||||
"column_break_2",
|
||||
"consultant_number",
|
||||
"consultant",
|
||||
"section_break_4",
|
||||
"account_number_length",
|
||||
"column_break_6",
|
||||
"consultant_number"
|
||||
"temporary_against_account_number"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -66,10 +67,17 @@
|
||||
"fieldtype": "Int",
|
||||
"label": "Account Number Length",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 1,
|
||||
"fieldname": "temporary_against_account_number",
|
||||
"fieldtype": "Data",
|
||||
"label": "Temporary Against Account Number",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-11-05 17:52:11.674329",
|
||||
"modified": "2020-11-19 19:00:09.088816",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "DATEV Settings",
|
||||
|
@ -1,53 +0,0 @@
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe import msgprint
|
||||
|
||||
|
||||
REQUIRED_FIELDS = {
|
||||
"Sales Invoice": [
|
||||
{
|
||||
"field_name": "company_address",
|
||||
"regulation": "§ 14 Abs. 4 Nr. 1 UStG"
|
||||
},
|
||||
{
|
||||
"field_name": "company_tax_id",
|
||||
"regulation": "§ 14 Abs. 4 Nr. 2 UStG"
|
||||
},
|
||||
{
|
||||
"field_name": "taxes",
|
||||
"regulation": "§ 14 Abs. 4 Nr. 8 UStG"
|
||||
},
|
||||
{
|
||||
"field_name": "customer_address",
|
||||
"regulation": "§ 14 Abs. 4 Nr. 1 UStG",
|
||||
"condition": "base_grand_total > 250"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def validate_regional(doc):
|
||||
"""Check if required fields for this document are present."""
|
||||
required_fields = REQUIRED_FIELDS.get(doc.doctype)
|
||||
if not required_fields:
|
||||
return
|
||||
|
||||
meta = frappe.get_meta(doc.doctype)
|
||||
field_map = {field.fieldname: field.label for field in meta.fields}
|
||||
|
||||
for field in required_fields:
|
||||
condition = field.get("condition")
|
||||
if condition and not frappe.safe_eval(condition, doc.as_dict()):
|
||||
continue
|
||||
|
||||
field_name = field.get("field_name")
|
||||
regulation = field.get("regulation")
|
||||
if field_name and not doc.get(field_name):
|
||||
missing(field_map.get(field_name), regulation)
|
||||
|
||||
|
||||
def missing(field_label, regulation):
|
||||
"""Notify the user that a required field is missing."""
|
||||
translated_msg = _('Remember to set {field_label}. It is required by {regulation}.', context='Specific for Germany. Example: Remember to set Company Tax ID. It is required by § 14 Abs. 4 Nr. 2 UStG.') # noqa: E501
|
||||
formatted_msg = translated_msg.format(field_label=frappe.bold(_(field_label)), regulation=regulation)
|
||||
msgprint(formatted_msg)
|
@ -1,12 +0,0 @@
|
||||
import frappe
|
||||
import unittest
|
||||
from erpnext.regional.germany.accounts_controller import validate_regional
|
||||
|
||||
|
||||
class TestAccountsController(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.sales_invoice = frappe.get_last_doc('Sales Invoice')
|
||||
|
||||
def test_validate_regional(self):
|
||||
validate_regional(self.sales_invoice)
|
@ -96,6 +96,8 @@ def execute(filters=None):
|
||||
"""Entry point for frappe."""
|
||||
data = []
|
||||
if filters and validate(filters):
|
||||
fn = 'temporary_against_account_number'
|
||||
filters[fn] = frappe.get_value('DATEV Settings', filters.get('company'), fn)
|
||||
data = get_transactions(filters, as_dict=0)
|
||||
|
||||
return COLUMNS, data
|
||||
@ -156,11 +158,11 @@ def get_transactions(filters, as_dict=1):
|
||||
case gl.debit when 0 then 'H' else 'S' end as 'Soll/Haben-Kennzeichen',
|
||||
|
||||
/* account number or, if empty, party account number */
|
||||
coalesce(acc.account_number, acc_pa.account_number) as 'Konto',
|
||||
acc.account_number as 'Konto',
|
||||
|
||||
/* against number or, if empty, party against number */
|
||||
coalesce(acc_against.account_number, acc_against_pa.account_number) as 'Gegenkonto (ohne BU-Schlüssel)',
|
||||
|
||||
%(temporary_against_account_number)s as 'Gegenkonto (ohne BU-Schlüssel)',
|
||||
|
||||
gl.posting_date as 'Belegdatum',
|
||||
gl.voucher_no as 'Belegfeld 1',
|
||||
LEFT(gl.remarks, 60) as 'Buchungstext',
|
||||
@ -171,27 +173,10 @@ def get_transactions(filters, as_dict=1):
|
||||
|
||||
FROM `tabGL Entry` gl
|
||||
|
||||
/* Statistisches Konto (Debitoren/Kreditoren) */
|
||||
left join `tabParty Account` pa
|
||||
on gl.against = pa.parent
|
||||
and gl.company = pa.company
|
||||
|
||||
/* Kontonummer */
|
||||
left join `tabAccount` acc
|
||||
on gl.account = acc.name
|
||||
|
||||
/* Gegenkonto-Nummer */
|
||||
left join `tabAccount` acc_against
|
||||
on gl.against = acc_against.name
|
||||
|
||||
/* Statistische Kontonummer */
|
||||
left join `tabAccount` acc_pa
|
||||
on pa.account = acc_pa.name
|
||||
|
||||
/* Statistische Gegenkonto-Nummer */
|
||||
left join `tabAccount` acc_against_pa
|
||||
on pa.account = acc_against_pa.name
|
||||
|
||||
WHERE gl.company = %(company)s
|
||||
AND DATE(gl.posting_date) >= %(from_date)s
|
||||
AND DATE(gl.posting_date) <= %(to_date)s
|
||||
@ -347,7 +332,9 @@ def download_datev_csv(filters):
|
||||
coa = frappe.get_value('Company', company, 'chart_of_accounts')
|
||||
filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
|
||||
|
||||
filters['account_number_length'] = frappe.get_value('DATEV Settings', company, 'account_number_length')
|
||||
datev_settings = frappe.get_doc('DATEV Settings', company)
|
||||
filters['account_number_length'] = datev_settings.account_number_length
|
||||
filters['temporary_against_account_number'] = datev_settings.temporary_against_account_number
|
||||
|
||||
transactions = get_transactions(filters)
|
||||
account_names = get_account_names(filters)
|
||||
|
@ -126,7 +126,8 @@ def make_datev_settings(company):
|
||||
"doctype": "DATEV Settings",
|
||||
"client": company.name,
|
||||
"client_number": "12345",
|
||||
"consultant_number": "67890"
|
||||
"consultant_number": "67890",
|
||||
"temporary_against_account_number": "9999"
|
||||
}).insert()
|
||||
|
||||
|
||||
@ -137,7 +138,8 @@ class TestDatev(TestCase):
|
||||
self.filters = {
|
||||
"company": self.company.name,
|
||||
"from_date": today(),
|
||||
"to_date": today()
|
||||
"to_date": today(),
|
||||
"temporary_against_account_number": "9999"
|
||||
}
|
||||
|
||||
make_datev_settings(self.company)
|
||||
|
@ -255,15 +255,16 @@ class Gstr1Report(object):
|
||||
|
||||
for item_code, tax_amounts in item_wise_tax_detail.items():
|
||||
tax_rate = tax_amounts[0]
|
||||
if cgst_or_sgst:
|
||||
tax_rate *= 2
|
||||
if parent not in self.cgst_sgst_invoices:
|
||||
self.cgst_sgst_invoices.append(parent)
|
||||
if tax_rate:
|
||||
if cgst_or_sgst:
|
||||
tax_rate *= 2
|
||||
if parent not in self.cgst_sgst_invoices:
|
||||
self.cgst_sgst_invoices.append(parent)
|
||||
|
||||
rate_based_dict = self.items_based_on_tax_rate\
|
||||
.setdefault(parent, {}).setdefault(tax_rate, [])
|
||||
if item_code not in rate_based_dict:
|
||||
rate_based_dict.append(item_code)
|
||||
rate_based_dict = self.items_based_on_tax_rate\
|
||||
.setdefault(parent, {}).setdefault(tax_rate, [])
|
||||
if item_code not in rate_based_dict:
|
||||
rate_based_dict.append(item_code)
|
||||
except ValueError:
|
||||
continue
|
||||
if unidentified_gst_accounts:
|
||||
|
@ -399,6 +399,10 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
}
|
||||
},
|
||||
|
||||
batch_no: function(doc, cdt, cdn) {
|
||||
this._super(doc, cdt, cdn);
|
||||
},
|
||||
|
||||
qty: function(doc, cdt, cdn) {
|
||||
this._super(doc, cdt, cdn);
|
||||
|
||||
|
@ -8,6 +8,8 @@ import unittest
|
||||
|
||||
from erpnext.stock.doctype.batch.batch import get_batch_qty, UnableToSelectBatchError, get_batch_no
|
||||
from frappe.utils import cint, flt
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
|
||||
class TestBatch(unittest.TestCase):
|
||||
def test_item_has_batch_enabled(self):
|
||||
@ -182,7 +184,7 @@ class TestBatch(unittest.TestCase):
|
||||
stock_entry.cancel()
|
||||
current_batch_qty = flt(frappe.db.get_value("Batch", "B100", "batch_qty"))
|
||||
self.assertEqual(current_batch_qty, existing_batch_qty)
|
||||
|
||||
|
||||
@classmethod
|
||||
def make_new_batch_and_entry(cls, item_name, batch_name, warehouse):
|
||||
'''Make a new stock entry for given target warehouse and batch name of item'''
|
||||
@ -252,6 +254,72 @@ class TestBatch(unittest.TestCase):
|
||||
|
||||
return batch
|
||||
|
||||
def test_batch_wise_item_price(self):
|
||||
if not frappe.db.get_value('Item', '_Test Batch Price Item'):
|
||||
frappe.get_doc({
|
||||
'doctype': 'Item',
|
||||
'is_stock_item': 1,
|
||||
'item_code': '_Test Batch Price Item',
|
||||
'item_group': 'Products',
|
||||
'has_batch_no': 1,
|
||||
'create_new_batch': 1
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
batch1 = create_batch('_Test Batch Price Item', 200, 1)
|
||||
batch2 = create_batch('_Test Batch Price Item', 300, 1)
|
||||
batch3 = create_batch('_Test Batch Price Item', 400, 0)
|
||||
|
||||
args = frappe._dict({
|
||||
"item_code": "_Test Batch Price Item",
|
||||
"company": "_Test Company with perpetual inventory",
|
||||
"price_list": "_Test Price List",
|
||||
"currency": "_Test Currency",
|
||||
"doctype": "Sales Invoice",
|
||||
"conversion_rate": 1,
|
||||
"price_list_currency": "_Test Currency",
|
||||
"plc_conversion_rate": 1,
|
||||
"customer": "_Test Customer",
|
||||
"name": None
|
||||
})
|
||||
|
||||
#test price for batch1
|
||||
args.update({'batch_no': batch1})
|
||||
details = get_item_details(args)
|
||||
self.assertEqual(details.get('price_list_rate'), 200)
|
||||
|
||||
#test price for batch2
|
||||
args.update({'batch_no': batch2})
|
||||
details = get_item_details(args)
|
||||
self.assertEqual(details.get('price_list_rate'), 300)
|
||||
|
||||
#test price for batch3
|
||||
args.update({'batch_no': batch3})
|
||||
details = get_item_details(args)
|
||||
self.assertEqual(details.get('price_list_rate'), 400)
|
||||
|
||||
def create_batch(item_code, rate, create_item_price_for_batch):
|
||||
pi = make_purchase_invoice(company="_Test Company with perpetual inventory",
|
||||
warehouse= "Stores - TCP1", cost_center = "Main - TCP1", update_stock=1,
|
||||
expense_account ="_Test Account Cost for Goods Sold - TCP1", item_code=item_code)
|
||||
|
||||
batch = frappe.db.get_value('Batch', {'item': item_code, 'reference_name': pi.name})
|
||||
|
||||
if not create_item_price_for_batch:
|
||||
create_price_list_for_batch(item_code, None, rate)
|
||||
else:
|
||||
create_price_list_for_batch(item_code, batch, rate)
|
||||
|
||||
return batch
|
||||
|
||||
def create_price_list_for_batch(item_code, batch, rate):
|
||||
frappe.get_doc({
|
||||
'doctype': 'Item Price',
|
||||
'item_code': '_Test Batch Price Item',
|
||||
'price_list': '_Test Price List',
|
||||
'batch_no': batch,
|
||||
'price_list_rate': rate
|
||||
}).insert()
|
||||
|
||||
def make_new_batch(**args):
|
||||
args = frappe._dict(args)
|
||||
|
||||
|
@ -106,9 +106,9 @@
|
||||
"item_tax_section_break",
|
||||
"taxes",
|
||||
"inspection_criteria",
|
||||
"quality_inspection_template",
|
||||
"inspection_required_before_purchase",
|
||||
"inspection_required_before_delivery",
|
||||
"quality_inspection_template",
|
||||
"manufacturing",
|
||||
"default_bom",
|
||||
"is_sub_contracted_item",
|
||||
@ -814,7 +814,6 @@
|
||||
"label": "Inspection Required before Delivery"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(doc.inspection_required_before_purchase || doc.inspection_required_before_delivery)",
|
||||
"fieldname": "quality_inspection_template",
|
||||
"fieldtype": "Link",
|
||||
"label": "Quality Inspection Template",
|
||||
@ -1069,7 +1068,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"max_attachments": 1,
|
||||
"modified": "2020-08-07 14:24:58.384992",
|
||||
"modified": "2021-01-25 20:49:50.222976",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item",
|
||||
@ -1131,4 +1130,4 @@
|
||||
"sort_order": "DESC",
|
||||
"title_field": "item_name",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
@ -15,5 +15,13 @@ frappe.ui.form.on("Item Price", {
|
||||
|
||||
frm.set_df_property("bulk_import_help", "options",
|
||||
'<a href="#data-import-tool/Item Price">' + __("Import in Bulk") + '</a>');
|
||||
|
||||
frm.set_query('batch_no', function() {
|
||||
return {
|
||||
filters: {
|
||||
'item': frm.doc.item_code
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -18,6 +18,7 @@
|
||||
"price_list",
|
||||
"customer",
|
||||
"supplier",
|
||||
"batch_no",
|
||||
"column_break_3",
|
||||
"buying",
|
||||
"selling",
|
||||
@ -47,31 +48,41 @@
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Item",
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
"search_index": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "UOM",
|
||||
"options": "UOM"
|
||||
"options": "UOM",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Quantity that must be bought or sold per UOM",
|
||||
"fieldname": "packing_unit",
|
||||
"fieldtype": "Int",
|
||||
"label": "Packing Unit"
|
||||
"label": "Packing Unit",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Name",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.brand",
|
||||
@ -79,19 +90,25 @@
|
||||
"fieldtype": "Read Only",
|
||||
"in_list_view": 1,
|
||||
"label": "Brand",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "item_description",
|
||||
"fieldtype": "Text",
|
||||
"label": "Item Description",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "price_list_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Price List",
|
||||
"options": "fa fa-tags"
|
||||
"options": "fa fa-tags",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "price_list",
|
||||
@ -100,7 +117,9 @@
|
||||
"in_standard_filter": 1,
|
||||
"label": "Price List",
|
||||
"options": "Price List",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
@ -108,37 +127,49 @@
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer",
|
||||
"options": "Customer"
|
||||
"options": "Customer",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.buying == 1",
|
||||
"fieldname": "supplier",
|
||||
"fieldtype": "Link",
|
||||
"label": "Supplier",
|
||||
"options": "Supplier"
|
||||
"options": "Supplier",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "buying",
|
||||
"fieldtype": "Check",
|
||||
"label": "Buying",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "selling",
|
||||
"fieldtype": "Check",
|
||||
"label": "Selling",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "item_details",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "fa fa-tag"
|
||||
"options": "fa fa-tag",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
@ -146,11 +177,15 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"read_only": 1
|
||||
"read_only": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "col_br_1",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "price_list_rate",
|
||||
@ -162,53 +197,80 @@
|
||||
"oldfieldname": "ref_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_15",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "valid_from",
|
||||
"fieldtype": "Date",
|
||||
"label": "Valid From"
|
||||
"label": "Valid From",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "lead_time_days",
|
||||
"fieldtype": "Int",
|
||||
"label": "Lead Time in days"
|
||||
"label": "Lead Time in days",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_18",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "valid_upto",
|
||||
"fieldtype": "Date",
|
||||
"label": "Valid Upto"
|
||||
"label": "Valid Upto",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_24",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "note",
|
||||
"fieldtype": "Text",
|
||||
"label": "Note"
|
||||
"label": "Note",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "reference",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Reference"
|
||||
"label": "Reference",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "batch_no",
|
||||
"fieldtype": "Link",
|
||||
"label": "Batch No",
|
||||
"options": "Batch",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-flag",
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-06 22:31:32.943475",
|
||||
"modified": "2020-12-08 18:12:15.395772",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item Price",
|
||||
|
@ -54,7 +54,8 @@ class ItemPrice(Document):
|
||||
"valid_upto",
|
||||
"packing_unit",
|
||||
"customer",
|
||||
"supplier",]:
|
||||
"supplier",
|
||||
"batch_no"]:
|
||||
if self.get(field):
|
||||
conditions += " and {0} = %({0})s ".format(field)
|
||||
else:
|
||||
@ -68,7 +69,7 @@ class ItemPrice(Document):
|
||||
self.as_dict(),)
|
||||
|
||||
if price_list_rate:
|
||||
frappe.throw(_("Item Price appears multiple times based on Price List, Supplier/Customer, Currency, Item, UOM, Qty, and Dates."), ItemPriceDuplicateItem,)
|
||||
frappe.throw(_("Item Price appears multiple times based on Price List, Supplier/Customer, Currency, Item, Batch, UOM, Qty, and Dates."), ItemPriceDuplicateItem,)
|
||||
|
||||
def before_save(self):
|
||||
if self.selling:
|
||||
|
@ -1,9 +1,10 @@
|
||||
frappe.listview_settings['Material Request'] = {
|
||||
add_fields: ["material_request_type", "status", "per_ordered", "per_received", "transfer_status"],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.status=="Stopped") {
|
||||
var precision = frappe.defaults.get_default("float_precision");
|
||||
if (doc.status=="Stopped") {
|
||||
return [__("Stopped"), "red", "status,=,Stopped"];
|
||||
} else if(doc.transfer_status && doc.docstatus != 2) {
|
||||
} else if (doc.transfer_status && doc.docstatus != 2) {
|
||||
if (doc.transfer_status == "Not Started") {
|
||||
return [__("Not Started"), "orange"];
|
||||
} else if (doc.transfer_status == "In Transit") {
|
||||
@ -11,14 +12,14 @@ frappe.listview_settings['Material Request'] = {
|
||||
} else if (doc.transfer_status == "Completed") {
|
||||
return [__("Completed"), "green"];
|
||||
}
|
||||
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 0) {
|
||||
} else if (doc.docstatus==1 && flt(doc.per_ordered, precision) == 0) {
|
||||
return [__("Pending"), "orange", "per_ordered,=,0"];
|
||||
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) {
|
||||
} else if (doc.docstatus==1 && flt(doc.per_ordered, precision) < 100) {
|
||||
return [__("Partially ordered"), "yellow", "per_ordered,<,100"];
|
||||
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 100) {
|
||||
if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) < 100 && flt(doc.per_received, 2) > 0) {
|
||||
} else if (doc.docstatus==1 && flt(doc.per_ordered, precision) == 100) {
|
||||
if (doc.material_request_type == "Purchase" && flt(doc.per_received, precision) < 100 && flt(doc.per_received, precision) > 0) {
|
||||
return [__("Partially Received"), "yellow", "per_received,<,100"];
|
||||
} else if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) == 100) {
|
||||
} else if (doc.material_request_type == "Purchase" && flt(doc.per_received, precision) == 100) {
|
||||
return [__("Received"), "green", "per_received,=,100"];
|
||||
} else if (doc.material_request_type == "Purchase") {
|
||||
return [__("Ordered"), "green", "per_ordered,=,100"];
|
||||
|
@ -5,6 +5,14 @@ frappe.provide("erpnext.accounts.dimensions");
|
||||
|
||||
frappe.ui.form.on('Stock Entry', {
|
||||
setup: function(frm) {
|
||||
frm.set_indicator_formatter('item_code', function(doc) {
|
||||
if (!doc.s_warehouse) {
|
||||
return 'blue';
|
||||
} else {
|
||||
return (doc.qty<=doc.actual_qty) ? 'green' : 'orange';
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query('work_order', function() {
|
||||
return {
|
||||
filters: [
|
||||
@ -779,15 +787,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
}
|
||||
}
|
||||
|
||||
this.frm.set_indicator_formatter('item_code',
|
||||
function(doc) {
|
||||
if (!doc.s_warehouse) {
|
||||
return 'blue';
|
||||
} else {
|
||||
return (doc.qty<=doc.actual_qty) ? "green" : "orange"
|
||||
}
|
||||
})
|
||||
|
||||
this.frm.add_fetch("purchase_order", "supplier", "supplier");
|
||||
|
||||
frappe.dynamic_link = { doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier' }
|
||||
|
@ -16,6 +16,7 @@
|
||||
"action_if_quality_inspection_is_not_submitted",
|
||||
"show_barcode_field",
|
||||
"clean_description_html",
|
||||
"disable_serial_no_and_batch_selector",
|
||||
"section_break_7",
|
||||
"auto_insert_price_list_rate_if_missing",
|
||||
"allow_negative_stock",
|
||||
@ -227,6 +228,12 @@
|
||||
"fieldname": "control_historical_stock_transactions_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Control Historical Stock Transactions"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "disable_serial_no_and_batch_selector",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable Serial No And Batch Selector"
|
||||
}
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
@ -234,7 +241,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2020-12-29 12:53:31.162247",
|
||||
"modified": "2021-01-18 13:15:38.352796",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Settings",
|
||||
|
@ -674,6 +674,8 @@ def get_item_price(args, item_code, ignore_party=False):
|
||||
and price_list=%(price_list)s
|
||||
and ifnull(uom, '') in ('', %(uom)s)"""
|
||||
|
||||
conditions += "and ifnull(batch_no, '') in ('', %(batch_no)s)"
|
||||
|
||||
if not ignore_party:
|
||||
if args.get("customer"):
|
||||
conditions += " and customer=%(customer)s"
|
||||
@ -692,7 +694,7 @@ def get_item_price(args, item_code, ignore_party=False):
|
||||
|
||||
return frappe.db.sql(""" select name, price_list_rate, uom
|
||||
from `tabItem Price` {conditions}
|
||||
order by valid_from desc, uom desc """.format(conditions=conditions), args)
|
||||
order by valid_from desc, batch_no desc, uom desc """.format(conditions=conditions), args)
|
||||
|
||||
def get_price_list_rate_for(args, item_code):
|
||||
"""
|
||||
@ -711,6 +713,7 @@ def get_price_list_rate_for(args, item_code):
|
||||
"uom": args.get('uom'),
|
||||
"transaction_date": args.get('transaction_date'),
|
||||
"posting_date": args.get('posting_date'),
|
||||
"batch_no": args.get('batch_no')
|
||||
}
|
||||
|
||||
item_price_data = 0
|
||||
|
@ -40,7 +40,7 @@
|
||||
<div class="col-md-{{ section.column_value }} mb-4">
|
||||
<div class="card h-100 justify-content-between">
|
||||
{% if card.image %}
|
||||
<div class="website-image-lazy" data-class="card-img-top h-100" data-src="{{ card.image }}" data-alt="{{ card.title }}"></div>
|
||||
<div class="website-image-lazy" data-class="card-img-top h-75" data-src="{{ card.image }}" data-alt="{{ card.title }}"></div>
|
||||
{% endif %}
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ card.title }}</h5>
|
||||
|
Loading…
x
Reference in New Issue
Block a user