mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-23 08:38:30 +00:00
Merge pull request #30741 from frappe/version-13-pre-release
chore: release for v13.27.0
This commit is contained in:
25
.github/workflows/release.yml
vendored
Normal file
25
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Generate Semantic Release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- version-13
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Entire Repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js v14
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
- name: Setup dependencies
|
||||
run: |
|
||||
npm install @semantic-release/git @semantic-release/exec --no-save
|
||||
- name: Create Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: npx semantic-release
|
||||
24
.releaserc
Normal file
24
.releaserc
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"branches": ["version-13"],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer", {
|
||||
"preset": "angular",
|
||||
"releaseRules": [
|
||||
{"breaking": true, "release": false}
|
||||
]
|
||||
},
|
||||
"@semantic-release/release-notes-generator",
|
||||
[
|
||||
"@semantic-release/exec", {
|
||||
"prepareCmd": 'sed -ir "s/[0-9]*\.[0-9]*\.[0-9]*/${nextRelease.version}/" erpnext/__init__.py'
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/git", {
|
||||
"assets": ["erpnext/__init__.py"],
|
||||
"message": "chore(release): Bumped to Version ${nextRelease.version}\n\n${nextRelease.notes}"
|
||||
}
|
||||
],
|
||||
"@semantic-release/github"
|
||||
]
|
||||
}
|
||||
@@ -205,10 +205,16 @@ def get_doctypes_with_dimensions():
|
||||
return frappe.get_hooks("accounting_dimension_doctypes")
|
||||
|
||||
|
||||
def get_accounting_dimensions(as_list=True):
|
||||
def get_accounting_dimensions(as_list=True, filters=None):
|
||||
|
||||
if not filters:
|
||||
filters = {"disabled": 0}
|
||||
|
||||
if frappe.flags.accounting_dimensions is None:
|
||||
frappe.flags.accounting_dimensions = frappe.get_all(
|
||||
"Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"]
|
||||
"Accounting Dimension",
|
||||
fields=["label", "fieldname", "disabled", "document_type"],
|
||||
filters=filters,
|
||||
)
|
||||
|
||||
if as_list:
|
||||
|
||||
@@ -19,7 +19,6 @@ from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category
|
||||
)
|
||||
from erpnext.accounts.party import get_party_account
|
||||
from erpnext.accounts.utils import (
|
||||
check_if_stock_and_account_balance_synced,
|
||||
get_account_currency,
|
||||
get_balance_on,
|
||||
get_stock_accounts,
|
||||
@@ -88,9 +87,6 @@ class JournalEntry(AccountsController):
|
||||
self.update_expense_claim()
|
||||
self.update_inter_company_jv()
|
||||
self.update_invoice_discounting()
|
||||
check_if_stock_and_account_balance_synced(
|
||||
self.posting_date, self.company, self.doctype, self.name
|
||||
)
|
||||
|
||||
def on_cancel(self):
|
||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||
|
||||
@@ -350,9 +350,13 @@ class PaymentReconciliation(Document):
|
||||
)
|
||||
|
||||
if self.minimum_invoice_amount:
|
||||
condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_invoice_amount))
|
||||
condition += " and {dr_or_cr} >= {amount}".format(
|
||||
dr_or_cr=dr_or_cr, amount=flt(self.minimum_invoice_amount)
|
||||
)
|
||||
if self.maximum_invoice_amount:
|
||||
condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_invoice_amount))
|
||||
condition += " and {dr_or_cr} <= {amount}".format(
|
||||
dr_or_cr=dr_or_cr, amount=flt(self.maximum_invoice_amount)
|
||||
)
|
||||
|
||||
elif get_return_invoices:
|
||||
condition = " and doc.company = '{0}' ".format(self.company)
|
||||
@@ -367,15 +371,19 @@ class PaymentReconciliation(Document):
|
||||
else ""
|
||||
)
|
||||
dr_or_cr = (
|
||||
"gl.debit_in_account_currency"
|
||||
"debit_in_account_currency"
|
||||
if erpnext.get_party_account_type(self.party_type) == "Receivable"
|
||||
else "gl.credit_in_account_currency"
|
||||
else "credit_in_account_currency"
|
||||
)
|
||||
|
||||
if self.minimum_invoice_amount:
|
||||
condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_payment_amount))
|
||||
condition += " and gl.{dr_or_cr} >= {amount}".format(
|
||||
dr_or_cr=dr_or_cr, amount=flt(self.minimum_payment_amount)
|
||||
)
|
||||
if self.maximum_invoice_amount:
|
||||
condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_payment_amount))
|
||||
condition += " and gl.{dr_or_cr} <= {amount}".format(
|
||||
dr_or_cr=dr_or_cr, amount=flt(self.maximum_payment_amount)
|
||||
)
|
||||
|
||||
else:
|
||||
condition += (
|
||||
|
||||
@@ -34,8 +34,9 @@ class ProcessStatementOfAccounts(Document):
|
||||
frappe.throw(_("Customers not selected."))
|
||||
|
||||
if self.enable_auto_email:
|
||||
self.to_date = self.start_date
|
||||
self.from_date = add_months(self.to_date, -1 * self.filter_duration)
|
||||
if self.start_date and getdate(self.start_date) >= getdate(today()):
|
||||
self.to_date = self.start_date
|
||||
self.from_date = add_months(self.to_date, -1 * self.filter_duration)
|
||||
|
||||
|
||||
def get_report_pdf(doc, consolidated=True):
|
||||
|
||||
@@ -30,6 +30,9 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
onload: function() {
|
||||
this._super();
|
||||
|
||||
// Ignore linked advances
|
||||
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry'];
|
||||
|
||||
if(!this.frm.doc.__islocal) {
|
||||
// show credit_to in print format
|
||||
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
|
||||
|
||||
@@ -801,7 +801,9 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
if provisional_accounting_for_non_stock_items:
|
||||
if item.purchase_receipt:
|
||||
provisional_account = self.get_company_default("default_provisional_account")
|
||||
provisional_account = frappe.db.get_value(
|
||||
"Purchase Receipt Item", item.pr_detail, "provisional_expense_account"
|
||||
) or self.get_company_default("default_provisional_account")
|
||||
purchase_receipt_doc = purchase_receipt_doc_map.get(item.purchase_receipt)
|
||||
|
||||
if not purchase_receipt_doc:
|
||||
@@ -824,7 +826,7 @@ class PurchaseInvoice(BuyingController):
|
||||
if expense_booked_in_pr:
|
||||
# Intentionally passing purchase invoice item to handle partial billing
|
||||
purchase_receipt_doc.add_provisional_gl_entry(
|
||||
item, gl_entries, self.posting_date, reverse=1
|
||||
item, gl_entries, self.posting_date, provisional_account, reverse=1
|
||||
)
|
||||
|
||||
if not self.is_internal_transfer():
|
||||
|
||||
@@ -1449,7 +1449,8 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)
|
||||
|
||||
def test_provisional_accounting_entry(self):
|
||||
item = create_item("_Test Non Stock Item", is_stock_item=0)
|
||||
create_item("_Test Non Stock Item", is_stock_item=0)
|
||||
|
||||
provisional_account = create_account(
|
||||
account_name="Provision Account",
|
||||
parent_account="Current Liabilities - _TC",
|
||||
@@ -1472,6 +1473,8 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
pi.save()
|
||||
pi.submit()
|
||||
|
||||
self.assertEquals(pr.items[0].provisional_expense_account, "Provision Account - _TC")
|
||||
|
||||
# Check GLE for Purchase Invoice
|
||||
expected_gle = [
|
||||
["Cost of Goods Sold - _TC", 250, 0, add_days(pr.posting_date, -1)],
|
||||
|
||||
@@ -34,7 +34,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
var me = this;
|
||||
this._super();
|
||||
|
||||
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log', 'POS Closing Entry'];
|
||||
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
|
||||
'POS Closing Entry', 'Journal Entry', 'Payment Entry'];
|
||||
|
||||
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
|
||||
// show debit_to in print format
|
||||
this.frm.set_df_property("debit_to", "print_hide", 0);
|
||||
|
||||
@@ -3062,6 +3062,62 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.reload()
|
||||
self.assertTrue(si.items[0].serial_no)
|
||||
|
||||
def test_gain_loss_with_advance_entry(self):
|
||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||
|
||||
unlink_enabled = frappe.db.get_value(
|
||||
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice"
|
||||
)
|
||||
|
||||
frappe.db.set_value(
|
||||
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", 1
|
||||
)
|
||||
|
||||
jv = make_journal_entry("_Test Receivable USD - _TC", "_Test Bank - _TC", -7000, save=False)
|
||||
|
||||
jv.accounts[0].exchange_rate = 70
|
||||
jv.accounts[0].credit_in_account_currency = 100
|
||||
jv.accounts[0].party_type = "Customer"
|
||||
jv.accounts[0].party = "_Test Customer USD"
|
||||
|
||||
jv.save()
|
||||
jv.submit()
|
||||
|
||||
si = create_sales_invoice(
|
||||
customer="_Test Customer USD",
|
||||
debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD",
|
||||
conversion_rate=75,
|
||||
do_not_save=1,
|
||||
rate=100,
|
||||
)
|
||||
|
||||
si.append(
|
||||
"advances",
|
||||
{
|
||||
"reference_type": "Journal Entry",
|
||||
"reference_name": jv.name,
|
||||
"reference_row": jv.accounts[0].name,
|
||||
"advance_amount": 100,
|
||||
"allocated_amount": 100,
|
||||
"ref_exchange_rate": 70,
|
||||
},
|
||||
)
|
||||
si.save()
|
||||
si.submit()
|
||||
|
||||
expected_gle = [
|
||||
["_Test Receivable USD - _TC", 7500.0, 500],
|
||||
["Exchange Gain/Loss - _TC", 500.0, 0.0],
|
||||
["Sales - _TC", 0.0, 7500.0],
|
||||
]
|
||||
|
||||
check_gl_entries(self, si.name, expected_gle, nowdate())
|
||||
|
||||
frappe.db.set_value(
|
||||
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", unlink_enabled
|
||||
)
|
||||
|
||||
|
||||
def get_sales_invoice_for_e_invoice():
|
||||
si = make_sales_invoice_for_ewaybill()
|
||||
|
||||
@@ -19,10 +19,6 @@ from erpnext.stock import get_warehouse_account_map
|
||||
from erpnext.stock.utils import get_stock_value_on
|
||||
|
||||
|
||||
class StockValueAndAccountBalanceOutOfSync(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class FiscalYearError(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
@@ -1247,47 +1243,6 @@ def compare_existing_and_expected_gle(existing_gle, expected_gle, precision):
|
||||
return matched
|
||||
|
||||
|
||||
def check_if_stock_and_account_balance_synced(
|
||||
posting_date, company, voucher_type=None, voucher_no=None
|
||||
):
|
||||
if not cint(erpnext.is_perpetual_inventory_enabled(company)):
|
||||
return
|
||||
|
||||
accounts = get_stock_accounts(company, voucher_type, voucher_no)
|
||||
stock_adjustment_account = frappe.db.get_value("Company", company, "stock_adjustment_account")
|
||||
|
||||
for account in accounts:
|
||||
account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
|
||||
account, posting_date, company
|
||||
)
|
||||
|
||||
if abs(account_bal - stock_bal) > 0.1:
|
||||
precision = get_field_precision(
|
||||
frappe.get_meta("GL Entry").get_field("debit"),
|
||||
currency=frappe.get_cached_value("Company", company, "default_currency"),
|
||||
)
|
||||
|
||||
diff = flt(stock_bal - account_bal, precision)
|
||||
|
||||
error_reason = _(
|
||||
"Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses as on {3}."
|
||||
).format(stock_bal, account_bal, frappe.bold(account), posting_date)
|
||||
error_resolution = _("Please create an adjustment Journal Entry for amount {0} on {1}").format(
|
||||
frappe.bold(diff), frappe.bold(posting_date)
|
||||
)
|
||||
|
||||
frappe.msgprint(
|
||||
msg="""{0}<br></br>{1}<br></br>""".format(error_reason, error_resolution),
|
||||
raise_exception=StockValueAndAccountBalanceOutOfSync,
|
||||
title=_("Values Out Of Sync"),
|
||||
primary_action={
|
||||
"label": _("Make Journal Entry"),
|
||||
"client_action": "erpnext.route_to_adjustment_jv",
|
||||
"args": get_journal_entry(account, stock_adjustment_account, diff),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def get_stock_accounts(company, voucher_type=None, voucher_no=None):
|
||||
stock_accounts = [
|
||||
d.name
|
||||
|
||||
@@ -364,7 +364,7 @@ class Asset(AccountsController):
|
||||
if has_pro_rata and n == 0:
|
||||
# For first entry of monthly depr
|
||||
if r == 0:
|
||||
days_until_first_depr = date_diff(monthly_schedule_date, self.available_for_use_date)
|
||||
days_until_first_depr = date_diff(monthly_schedule_date, self.available_for_use_date) + 1
|
||||
per_day_amt = depreciation_amount / days
|
||||
depreciation_amount_for_current_month = per_day_amt * days_until_first_depr
|
||||
depreciation_amount -= depreciation_amount_for_current_month
|
||||
|
||||
@@ -2000,12 +2000,13 @@ def get_advance_journal_entries(
|
||||
|
||||
reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
|
||||
|
||||
# nosemgrep
|
||||
journal_entries = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
"Journal Entry" as reference_type, t1.name as reference_name,
|
||||
t1.remark as remarks, t2.{0} as amount, t2.name as reference_row,
|
||||
t2.reference_name as against_order
|
||||
t2.reference_name as against_order, t2.exchange_rate
|
||||
from
|
||||
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
||||
where
|
||||
|
||||
@@ -462,6 +462,7 @@ class ProductionPlan(Document):
|
||||
work_order_data = {
|
||||
"wip_warehouse": default_warehouses.get("wip_warehouse"),
|
||||
"fg_warehouse": default_warehouses.get("fg_warehouse"),
|
||||
"company": self.get("company"),
|
||||
}
|
||||
|
||||
self.prepare_data_for_sub_assembly_items(row, work_order_data)
|
||||
@@ -499,6 +500,7 @@ class ProductionPlan(Document):
|
||||
|
||||
for supplier, po_list in subcontracted_po.items():
|
||||
po = frappe.new_doc("Purchase Order")
|
||||
po.company = self.company
|
||||
po.supplier = supplier
|
||||
po.schedule_date = getdate(po_list[0].schedule_date) if po_list[0].schedule_date else nowdate()
|
||||
po.is_subcontracted = "Yes"
|
||||
|
||||
@@ -350,6 +350,7 @@ erpnext.patches.v13_0.enable_provisional_accounting
|
||||
erpnext.patches.v13_0.update_disbursement_account
|
||||
erpnext.patches.v13_0.update_reserved_qty_closed_wo
|
||||
erpnext.patches.v13_0.amazon_mws_deprecation_warning
|
||||
erpnext.patches.v13_0.datev_deprecation_warning
|
||||
erpnext.patches.v13_0.set_work_order_qty_in_so_from_mr
|
||||
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
||||
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
|
||||
|
||||
9
erpnext/patches/v13_0/datev_deprecation_warning.py
Normal file
9
erpnext/patches/v13_0/datev_deprecation_warning.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import click
|
||||
|
||||
|
||||
def execute():
|
||||
click.secho(
|
||||
"DATEV reports are moved to a separate app and will be removed from ERPNext in version-14.\n"
|
||||
"Please install the app to continue using them: https://github.com/alyf-de/erpnext_datev",
|
||||
fg="yellow",
|
||||
)
|
||||
@@ -10,54 +10,58 @@ def execute():
|
||||
|
||||
frappe.reload_doc("hr", "doctype", "Leave Encashment")
|
||||
|
||||
additional_salaries = frappe.get_all(
|
||||
"Additional Salary",
|
||||
fields=["name", "salary_slip", "type", "salary_component"],
|
||||
filters={"salary_slip": ["!=", ""]},
|
||||
group_by="salary_slip",
|
||||
)
|
||||
leave_encashments = frappe.get_all(
|
||||
"Leave Encashment",
|
||||
fields=["name", "additional_salary"],
|
||||
filters={"additional_salary": ["!=", ""]},
|
||||
)
|
||||
employee_incentives = frappe.get_all(
|
||||
"Employee Incentive",
|
||||
fields=["name", "additional_salary"],
|
||||
filters={"additional_salary": ["!=", ""]},
|
||||
)
|
||||
|
||||
for incentive in employee_incentives:
|
||||
frappe.db.sql(
|
||||
""" UPDATE `tabAdditional Salary`
|
||||
SET ref_doctype = 'Employee Incentive', ref_docname = %s
|
||||
WHERE name = %s
|
||||
""",
|
||||
(incentive["name"], incentive["additional_salary"]),
|
||||
if frappe.db.has_column("Leave Encashment", "additional_salary"):
|
||||
leave_encashments = frappe.get_all(
|
||||
"Leave Encashment",
|
||||
fields=["name", "additional_salary"],
|
||||
filters={"additional_salary": ["!=", ""]},
|
||||
)
|
||||
|
||||
for leave_encashment in leave_encashments:
|
||||
frappe.db.sql(
|
||||
""" UPDATE `tabAdditional Salary`
|
||||
SET ref_doctype = 'Leave Encashment', ref_docname = %s
|
||||
WHERE name = %s
|
||||
""",
|
||||
(leave_encashment["name"], leave_encashment["additional_salary"]),
|
||||
)
|
||||
|
||||
salary_slips = [sal["salary_slip"] for sal in additional_salaries]
|
||||
|
||||
for salary in additional_salaries:
|
||||
comp_type = "earnings" if salary["type"] == "Earning" else "deductions"
|
||||
if salary["salary_slip"] and salary_slips.count(salary["salary_slip"]) == 1:
|
||||
for leave_encashment in leave_encashments:
|
||||
frappe.db.sql(
|
||||
"""
|
||||
UPDATE `tabSalary Detail`
|
||||
SET additional_salary = %s
|
||||
WHERE parenttype = 'Salary Slip'
|
||||
and parentfield = %s
|
||||
and parent = %s
|
||||
and salary_component = %s
|
||||
""" UPDATE `tabAdditional Salary`
|
||||
SET ref_doctype = 'Leave Encashment', ref_docname = %s
|
||||
WHERE name = %s
|
||||
""",
|
||||
(salary["name"], comp_type, salary["salary_slip"], salary["salary_component"]),
|
||||
(leave_encashment["name"], leave_encashment["additional_salary"]),
|
||||
)
|
||||
|
||||
if frappe.db.has_column("Employee Incentive", "additional_salary"):
|
||||
employee_incentives = frappe.get_all(
|
||||
"Employee Incentive",
|
||||
fields=["name", "additional_salary"],
|
||||
filters={"additional_salary": ["!=", ""]},
|
||||
)
|
||||
|
||||
for incentive in employee_incentives:
|
||||
frappe.db.sql(
|
||||
""" UPDATE `tabAdditional Salary`
|
||||
SET ref_doctype = 'Employee Incentive', ref_docname = %s
|
||||
WHERE name = %s
|
||||
""",
|
||||
(incentive["name"], incentive["additional_salary"]),
|
||||
)
|
||||
|
||||
if frappe.db.has_column("Additional Salary", "salary_slip"):
|
||||
additional_salaries = frappe.get_all(
|
||||
"Additional Salary",
|
||||
fields=["name", "salary_slip", "type", "salary_component"],
|
||||
filters={"salary_slip": ["!=", ""]},
|
||||
group_by="salary_slip",
|
||||
)
|
||||
|
||||
salary_slips = [sal["salary_slip"] for sal in additional_salaries]
|
||||
|
||||
for salary in additional_salaries:
|
||||
comp_type = "earnings" if salary["type"] == "Earning" else "deductions"
|
||||
if salary["salary_slip"] and salary_slips.count(salary["salary_slip"]) == 1:
|
||||
frappe.db.sql(
|
||||
"""
|
||||
UPDATE `tabSalary Detail`
|
||||
SET additional_salary = %s
|
||||
WHERE parenttype = 'Salary Slip'
|
||||
and parentfield = %s
|
||||
and parent = %s
|
||||
and salary_component = %s
|
||||
""",
|
||||
(salary["name"], comp_type, salary["salary_slip"], salary["salary_component"]),
|
||||
)
|
||||
|
||||
@@ -1500,6 +1500,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
// Target doc created from a mapped doc
|
||||
if (this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.frm.call({
|
||||
method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule",
|
||||
args: { args: args, doc: me.frm.doc },
|
||||
@@ -1616,7 +1621,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
me.remove_pricing_rule(frappe.get_doc(d.doctype, d.name));
|
||||
}
|
||||
|
||||
if (d.free_item_data) {
|
||||
if (d.free_item_data.length > 0) {
|
||||
me.apply_product_discount(d);
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,8 @@ erpnext.company.setup_queries = function(frm) {
|
||||
["expenses_included_in_asset_valuation", {"account_type": "Expenses Included In Asset Valuation"}],
|
||||
["capital_work_in_progress_account", {"account_type": "Capital Work in Progress"}],
|
||||
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}],
|
||||
["unrealized_profit_loss_account", {"root_type": ["in", ["Liability", "Asset"]]}]
|
||||
["unrealized_profit_loss_account", {"root_type": ["in", ["Liability", "Asset"]]}],
|
||||
["default_provisional_account", {"root_type": ["in", ["Liability", "Asset"]]}]
|
||||
], function(i, v) {
|
||||
erpnext.company.set_custom_query(frm, v);
|
||||
});
|
||||
|
||||
@@ -377,6 +377,17 @@ $.extend(erpnext.item, {
|
||||
}
|
||||
}
|
||||
|
||||
frm.set_query('default_provisional_account', 'item_defaults', (doc, cdt, cdn) => {
|
||||
let row = locals[cdt][cdn];
|
||||
return {
|
||||
filters: {
|
||||
"company": row.company,
|
||||
"root_type": ["in", ["Liability", "Asset"]],
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
make_dashboard: function(frm) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"default_supplier",
|
||||
"column_break_8",
|
||||
"expense_account",
|
||||
"default_provisional_account",
|
||||
"selling_defaults",
|
||||
"selling_cost_center",
|
||||
"column_break_12",
|
||||
@@ -101,11 +102,17 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Discount Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "default_provisional_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Provisional Account",
|
||||
"options": "Account"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-07-13 01:26:03.860065",
|
||||
"modified": "2022-04-10 20:18:54.148195",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item Default",
|
||||
@@ -114,5 +121,6 @@
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
||||
@@ -106,8 +106,6 @@
|
||||
"terms",
|
||||
"bill_no",
|
||||
"bill_date",
|
||||
"accounting_details_section",
|
||||
"provisional_expense_account",
|
||||
"more_info",
|
||||
"project",
|
||||
"status",
|
||||
@@ -1146,26 +1144,13 @@
|
||||
"label": "Represents Company",
|
||||
"options": "Company",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "accounting_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Accounting Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "provisional_expense_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Provisional Expense Account",
|
||||
"options": "Account"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-truck",
|
||||
"idx": 261,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-03-10 11:40:52.690984",
|
||||
"modified": "2022-04-10 22:50:37.761362",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt",
|
||||
|
||||
@@ -146,10 +146,13 @@ class PurchaseReceipt(BuyingController):
|
||||
)
|
||||
)
|
||||
|
||||
if provisional_accounting_for_non_stock_items:
|
||||
default_provisional_account = self.get_company_default("default_provisional_account")
|
||||
if not self.provisional_expense_account:
|
||||
self.provisional_expense_account = default_provisional_account
|
||||
if not provisional_accounting_for_non_stock_items:
|
||||
return
|
||||
|
||||
default_provisional_account = self.get_company_default("default_provisional_account")
|
||||
for item in self.get("items"):
|
||||
if not item.get("provisional_expense_account"):
|
||||
item.provisional_expense_account = default_provisional_account
|
||||
|
||||
def validate_with_previous_doc(self):
|
||||
super(PurchaseReceipt, self).validate_with_previous_doc(
|
||||
@@ -466,7 +469,9 @@ class PurchaseReceipt(BuyingController):
|
||||
and flt(d.qty)
|
||||
and provisional_accounting_for_non_stock_items
|
||||
):
|
||||
self.add_provisional_gl_entry(d, gl_entries, self.posting_date)
|
||||
self.add_provisional_gl_entry(
|
||||
d, gl_entries, self.posting_date, d.get("provisional_expense_account")
|
||||
)
|
||||
|
||||
if warehouse_with_no_account:
|
||||
frappe.msgprint(
|
||||
@@ -475,9 +480,10 @@ class PurchaseReceipt(BuyingController):
|
||||
+ "\n".join(warehouse_with_no_account)
|
||||
)
|
||||
|
||||
def add_provisional_gl_entry(self, item, gl_entries, posting_date, reverse=0):
|
||||
provisional_expense_account = self.get("provisional_expense_account")
|
||||
credit_currency = get_account_currency(provisional_expense_account)
|
||||
def add_provisional_gl_entry(
|
||||
self, item, gl_entries, posting_date, provisional_account, reverse=0
|
||||
):
|
||||
credit_currency = get_account_currency(provisional_account)
|
||||
debit_currency = get_account_currency(item.expense_account)
|
||||
expense_account = item.expense_account
|
||||
remarks = self.get("remarks") or _("Accounting Entry for Service")
|
||||
@@ -491,7 +497,7 @@ class PurchaseReceipt(BuyingController):
|
||||
|
||||
self.add_gl_entry(
|
||||
gl_entries=gl_entries,
|
||||
account=provisional_expense_account,
|
||||
account=provisional_account,
|
||||
cost_center=item.cost_center,
|
||||
debit=0.0,
|
||||
credit=multiplication_factor * item.amount,
|
||||
@@ -511,7 +517,7 @@ class PurchaseReceipt(BuyingController):
|
||||
debit=multiplication_factor * item.amount,
|
||||
credit=0.0,
|
||||
remarks=remarks,
|
||||
against_account=provisional_expense_account,
|
||||
against_account=provisional_account,
|
||||
account_currency=debit_currency,
|
||||
project=item.project,
|
||||
voucher_detail_no=item.name,
|
||||
|
||||
@@ -96,7 +96,6 @@
|
||||
"include_exploded_items",
|
||||
"batch_no",
|
||||
"rejected_serial_no",
|
||||
"expense_account",
|
||||
"item_tax_rate",
|
||||
"item_weight_details",
|
||||
"weight_per_unit",
|
||||
@@ -107,6 +106,10 @@
|
||||
"manufacturer",
|
||||
"column_break_16",
|
||||
"manufacturer_part_no",
|
||||
"accounting_details_section",
|
||||
"expense_account",
|
||||
"column_break_102",
|
||||
"provisional_expense_account",
|
||||
"accounting_dimensions_section",
|
||||
"project",
|
||||
"dimension_col_break",
|
||||
@@ -971,12 +974,27 @@
|
||||
"label": "Product Bundle",
|
||||
"options": "Product Bundle",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "provisional_expense_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Provisional Expense Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "accounting_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Accounting Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_102",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-02-01 11:32:27.980524",
|
||||
"modified": "2022-04-11 13:07:32.061402",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt Item",
|
||||
|
||||
@@ -4,15 +4,12 @@
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime, today
|
||||
from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime
|
||||
from frappe.utils.user import get_users_with_role
|
||||
from rq.timeouts import JobTimeoutException
|
||||
|
||||
import erpnext
|
||||
from erpnext.accounts.utils import (
|
||||
check_if_stock_and_account_balance_synced,
|
||||
update_gl_entries_after,
|
||||
)
|
||||
from erpnext.accounts.utils import update_gl_entries_after
|
||||
from erpnext.stock.stock_ledger import get_items_to_be_repost, repost_future_sle
|
||||
|
||||
|
||||
@@ -224,6 +221,10 @@ def notify_error_to_stock_managers(doc, traceback):
|
||||
|
||||
|
||||
def repost_entries():
|
||||
"""
|
||||
Reposts 'Repost Item Valuation' entries in queue.
|
||||
Called hourly via hooks.py.
|
||||
"""
|
||||
if not in_configured_timeslot():
|
||||
return
|
||||
|
||||
@@ -239,9 +240,6 @@ def repost_entries():
|
||||
if riv_entries:
|
||||
return
|
||||
|
||||
for d in frappe.get_all("Company", filters={"enable_perpetual_inventory": 1}):
|
||||
check_if_stock_and_account_balance_synced(today(), d.name)
|
||||
|
||||
|
||||
def get_repost_item_valuation_entries():
|
||||
return frappe.db.sql(
|
||||
|
||||
@@ -335,6 +335,7 @@ def get_basic_details(args, item, overwrite_warehouse=True):
|
||||
"expense_account": expense_account
|
||||
or get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults),
|
||||
"discount_account": get_default_discount_account(args, item_defaults),
|
||||
"provisional_expense_account": get_provisional_account(args, item_defaults),
|
||||
"cost_center": get_default_cost_center(
|
||||
args, item_defaults, item_group_defaults, brand_defaults
|
||||
),
|
||||
@@ -689,6 +690,10 @@ def get_default_expense_account(args, item, item_group, brand):
|
||||
)
|
||||
|
||||
|
||||
def get_provisional_account(args, item):
|
||||
return item.get("default_provisional_account") or args.default_provisional_account
|
||||
|
||||
|
||||
def get_default_discount_account(args, item):
|
||||
return item.get("default_discount_account") or args.discount_account
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ Assessment Report,Rapport d'Évaluation,
|
||||
Assessment Reports,Rapports d'évaluation,
|
||||
Assessment Result,Résultat de l'Évaluation,
|
||||
Assessment Result record {0} already exists.,Le Résultat d'Évaluation {0} existe déjà.,
|
||||
Asset,Atout,
|
||||
Asset,Actif - Immo.,
|
||||
Asset Category,Catégorie d'Actif,
|
||||
Asset Category is mandatory for Fixed Asset item,Catégorie d'Actif est obligatoire pour l'article Immobilisé,
|
||||
Asset Maintenance,Maintenance des actifs,
|
||||
@@ -3037,6 +3037,7 @@ To Date must be greater than From Date,La date de fin doit être supérieure à
|
||||
To Date should be within the Fiscal Year. Assuming To Date = {0},La Date Finale doit être dans l'exercice. En supposant Date Finale = {0},
|
||||
To Datetime,À la Date,
|
||||
To Deliver,À Livrer,
|
||||
{} To Deliver,{} à livrer
|
||||
To Deliver and Bill,À Livrer et Facturer,
|
||||
To Fiscal Year,À l'année fiscale,
|
||||
To GSTIN,GSTIN (Destination),
|
||||
@@ -9872,3 +9873,4 @@ Show Barcode Field in Stock Transactions,Afficher le champ Code Barre dans les t
|
||||
Convert Item Description to Clean HTML in Transactions,Convertir les descriptions d'articles en HTML valide lors des transactions
|
||||
Have Default Naming Series for Batch ID?,Nom de série par défaut pour les Lots ou Séries
|
||||
"The percentage you are allowed to transfer more against the quantity ordered. For example, if you have ordered 100 units, and your Allowance is 10%, then you are allowed transfer 110 units","Le pourcentage de quantité que vous pourrez réceptionner en plus de la quantité commandée. Par exemple, vous avez commandé 100 unités, votre pourcentage de dépassement est de 10%, vous pourrez réceptionner 110 unités"
|
||||
Unit Of Measure (UOM),Unité de mesure (UDM),
|
||||
|
||||
|
Can't render this file because it is too large.
|
0
erpnext/www/shop-by-category/__init__.py
Normal file
0
erpnext/www/shop-by-category/__init__.py
Normal file
Reference in New Issue
Block a user