mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 11:49:10 +00:00
Merge pull request #30740 from frappe/version-13-hotfix
chore: Pre-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.GITHUB_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")
|
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:
|
if frappe.flags.accounting_dimensions is None:
|
||||||
frappe.flags.accounting_dimensions = frappe.get_all(
|
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:
|
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.party import get_party_account
|
||||||
from erpnext.accounts.utils import (
|
from erpnext.accounts.utils import (
|
||||||
check_if_stock_and_account_balance_synced,
|
|
||||||
get_account_currency,
|
get_account_currency,
|
||||||
get_balance_on,
|
get_balance_on,
|
||||||
get_stock_accounts,
|
get_stock_accounts,
|
||||||
@@ -88,9 +87,6 @@ class JournalEntry(AccountsController):
|
|||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
self.update_inter_company_jv()
|
self.update_inter_company_jv()
|
||||||
self.update_invoice_discounting()
|
self.update_invoice_discounting()
|
||||||
check_if_stock_and_account_balance_synced(
|
|
||||||
self.posting_date, self.company, self.doctype, self.name
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||||
|
|||||||
@@ -350,9 +350,13 @@ class PaymentReconciliation(Document):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if self.minimum_invoice_amount:
|
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:
|
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:
|
elif get_return_invoices:
|
||||||
condition = " and doc.company = '{0}' ".format(self.company)
|
condition = " and doc.company = '{0}' ".format(self.company)
|
||||||
@@ -367,15 +371,19 @@ class PaymentReconciliation(Document):
|
|||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
dr_or_cr = (
|
dr_or_cr = (
|
||||||
"gl.debit_in_account_currency"
|
"debit_in_account_currency"
|
||||||
if erpnext.get_party_account_type(self.party_type) == "Receivable"
|
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:
|
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:
|
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:
|
else:
|
||||||
condition += (
|
condition += (
|
||||||
|
|||||||
@@ -34,8 +34,9 @@ class ProcessStatementOfAccounts(Document):
|
|||||||
frappe.throw(_("Customers not selected."))
|
frappe.throw(_("Customers not selected."))
|
||||||
|
|
||||||
if self.enable_auto_email:
|
if self.enable_auto_email:
|
||||||
self.to_date = self.start_date
|
if self.start_date and getdate(self.start_date) >= getdate(today()):
|
||||||
self.from_date = add_months(self.to_date, -1 * self.filter_duration)
|
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):
|
def get_report_pdf(doc, consolidated=True):
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
onload: function() {
|
onload: function() {
|
||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
|
// Ignore linked advances
|
||||||
|
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry'];
|
||||||
|
|
||||||
if(!this.frm.doc.__islocal) {
|
if(!this.frm.doc.__islocal) {
|
||||||
// show credit_to in print format
|
// show credit_to in print format
|
||||||
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
|
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 provisional_accounting_for_non_stock_items:
|
||||||
if item.purchase_receipt:
|
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)
|
purchase_receipt_doc = purchase_receipt_doc_map.get(item.purchase_receipt)
|
||||||
|
|
||||||
if not purchase_receipt_doc:
|
if not purchase_receipt_doc:
|
||||||
@@ -824,7 +826,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if expense_booked_in_pr:
|
if expense_booked_in_pr:
|
||||||
# Intentionally passing purchase invoice item to handle partial billing
|
# Intentionally passing purchase invoice item to handle partial billing
|
||||||
purchase_receipt_doc.add_provisional_gl_entry(
|
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():
|
if not self.is_internal_transfer():
|
||||||
|
|||||||
@@ -1449,7 +1449,8 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)
|
self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)
|
||||||
|
|
||||||
def test_provisional_accounting_entry(self):
|
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(
|
provisional_account = create_account(
|
||||||
account_name="Provision Account",
|
account_name="Provision Account",
|
||||||
parent_account="Current Liabilities - _TC",
|
parent_account="Current Liabilities - _TC",
|
||||||
@@ -1472,6 +1473,8 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
pi.save()
|
pi.save()
|
||||||
pi.submit()
|
pi.submit()
|
||||||
|
|
||||||
|
self.assertEquals(pr.items[0].provisional_expense_account, "Provision Account - _TC")
|
||||||
|
|
||||||
# Check GLE for Purchase Invoice
|
# Check GLE for Purchase Invoice
|
||||||
expected_gle = [
|
expected_gle = [
|
||||||
["Cost of Goods Sold - _TC", 250, 0, add_days(pr.posting_date, -1)],
|
["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;
|
var me = this;
|
||||||
this._super();
|
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) {
|
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
|
||||||
// show debit_to in print format
|
// show debit_to in print format
|
||||||
this.frm.set_df_property("debit_to", "print_hide", 0);
|
this.frm.set_df_property("debit_to", "print_hide", 0);
|
||||||
|
|||||||
@@ -3062,6 +3062,62 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.reload()
|
si.reload()
|
||||||
self.assertTrue(si.items[0].serial_no)
|
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():
|
def get_sales_invoice_for_e_invoice():
|
||||||
si = make_sales_invoice_for_ewaybill()
|
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
|
from erpnext.stock.utils import get_stock_value_on
|
||||||
|
|
||||||
|
|
||||||
class StockValueAndAccountBalanceOutOfSync(frappe.ValidationError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class FiscalYearError(frappe.ValidationError):
|
class FiscalYearError(frappe.ValidationError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -1247,47 +1243,6 @@ def compare_existing_and_expected_gle(existing_gle, expected_gle, precision):
|
|||||||
return matched
|
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):
|
def get_stock_accounts(company, voucher_type=None, voucher_no=None):
|
||||||
stock_accounts = [
|
stock_accounts = [
|
||||||
d.name
|
d.name
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ class Asset(AccountsController):
|
|||||||
if has_pro_rata and n == 0:
|
if has_pro_rata and n == 0:
|
||||||
# For first entry of monthly depr
|
# For first entry of monthly depr
|
||||||
if r == 0:
|
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
|
per_day_amt = depreciation_amount / days
|
||||||
depreciation_amount_for_current_month = per_day_amt * days_until_first_depr
|
depreciation_amount_for_current_month = per_day_amt * days_until_first_depr
|
||||||
depreciation_amount -= depreciation_amount_for_current_month
|
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 ""
|
reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
|
||||||
|
|
||||||
|
# nosemgrep
|
||||||
journal_entries = frappe.db.sql(
|
journal_entries = frappe.db.sql(
|
||||||
"""
|
"""
|
||||||
select
|
select
|
||||||
"Journal Entry" as reference_type, t1.name as reference_name,
|
"Journal Entry" as reference_type, t1.name as reference_name,
|
||||||
t1.remark as remarks, t2.{0} as amount, t2.name as reference_row,
|
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
|
from
|
||||||
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -462,6 +462,7 @@ class ProductionPlan(Document):
|
|||||||
work_order_data = {
|
work_order_data = {
|
||||||
"wip_warehouse": default_warehouses.get("wip_warehouse"),
|
"wip_warehouse": default_warehouses.get("wip_warehouse"),
|
||||||
"fg_warehouse": default_warehouses.get("fg_warehouse"),
|
"fg_warehouse": default_warehouses.get("fg_warehouse"),
|
||||||
|
"company": self.get("company"),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.prepare_data_for_sub_assembly_items(row, work_order_data)
|
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():
|
for supplier, po_list in subcontracted_po.items():
|
||||||
po = frappe.new_doc("Purchase Order")
|
po = frappe.new_doc("Purchase Order")
|
||||||
|
po.company = self.company
|
||||||
po.supplier = supplier
|
po.supplier = supplier
|
||||||
po.schedule_date = getdate(po_list[0].schedule_date) if po_list[0].schedule_date else nowdate()
|
po.schedule_date = getdate(po_list[0].schedule_date) if po_list[0].schedule_date else nowdate()
|
||||||
po.is_subcontracted = "Yes"
|
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_disbursement_account
|
||||||
erpnext.patches.v13_0.update_reserved_qty_closed_wo
|
erpnext.patches.v13_0.update_reserved_qty_closed_wo
|
||||||
erpnext.patches.v13_0.amazon_mws_deprecation_warning
|
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.set_work_order_qty_in_so_from_mr
|
||||||
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
||||||
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
|
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")
|
frappe.reload_doc("hr", "doctype", "Leave Encashment")
|
||||||
|
|
||||||
additional_salaries = frappe.get_all(
|
if frappe.db.has_column("Leave Encashment", "additional_salary"):
|
||||||
"Additional Salary",
|
leave_encashments = frappe.get_all(
|
||||||
fields=["name", "salary_slip", "type", "salary_component"],
|
"Leave Encashment",
|
||||||
filters={"salary_slip": ["!=", ""]},
|
fields=["name", "additional_salary"],
|
||||||
group_by="salary_slip",
|
filters={"additional_salary": ["!=", ""]},
|
||||||
)
|
|
||||||
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"]),
|
|
||||||
)
|
)
|
||||||
|
for leave_encashment in leave_encashments:
|
||||||
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:
|
|
||||||
frappe.db.sql(
|
frappe.db.sql(
|
||||||
"""
|
""" UPDATE `tabAdditional Salary`
|
||||||
UPDATE `tabSalary Detail`
|
SET ref_doctype = 'Leave Encashment', ref_docname = %s
|
||||||
SET additional_salary = %s
|
WHERE name = %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"]),
|
(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;
|
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({
|
return this.frm.call({
|
||||||
method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule",
|
method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule",
|
||||||
args: { args: args, doc: me.frm.doc },
|
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));
|
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);
|
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"}],
|
["expenses_included_in_asset_valuation", {"account_type": "Expenses Included In Asset Valuation"}],
|
||||||
["capital_work_in_progress_account", {"account_type": "Capital Work in Progress"}],
|
["capital_work_in_progress_account", {"account_type": "Capital Work in Progress"}],
|
||||||
["asset_received_but_not_billed", {"account_type": "Asset Received But Not Billed"}],
|
["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) {
|
], function(i, v) {
|
||||||
erpnext.company.set_custom_query(frm, 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) {
|
make_dashboard: function(frm) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"default_supplier",
|
"default_supplier",
|
||||||
"column_break_8",
|
"column_break_8",
|
||||||
"expense_account",
|
"expense_account",
|
||||||
|
"default_provisional_account",
|
||||||
"selling_defaults",
|
"selling_defaults",
|
||||||
"selling_cost_center",
|
"selling_cost_center",
|
||||||
"column_break_12",
|
"column_break_12",
|
||||||
@@ -101,11 +102,17 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Default Discount Account",
|
"label": "Default Discount Account",
|
||||||
"options": "Account"
|
"options": "Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "default_provisional_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Default Provisional Account",
|
||||||
|
"options": "Account"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-07-13 01:26:03.860065",
|
"modified": "2022-04-10 20:18:54.148195",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item Default",
|
"name": "Item Default",
|
||||||
@@ -114,5 +121,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -106,8 +106,6 @@
|
|||||||
"terms",
|
"terms",
|
||||||
"bill_no",
|
"bill_no",
|
||||||
"bill_date",
|
"bill_date",
|
||||||
"accounting_details_section",
|
|
||||||
"provisional_expense_account",
|
|
||||||
"more_info",
|
"more_info",
|
||||||
"project",
|
"project",
|
||||||
"status",
|
"status",
|
||||||
@@ -1146,26 +1144,13 @@
|
|||||||
"label": "Represents Company",
|
"label": "Represents Company",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"read_only": 1
|
"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",
|
"icon": "fa fa-truck",
|
||||||
"idx": 261,
|
"idx": 261,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-03-10 11:40:52.690984",
|
"modified": "2022-04-10 22:50:37.761362",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt",
|
"name": "Purchase Receipt",
|
||||||
|
|||||||
@@ -146,10 +146,13 @@ class PurchaseReceipt(BuyingController):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if provisional_accounting_for_non_stock_items:
|
if not provisional_accounting_for_non_stock_items:
|
||||||
default_provisional_account = self.get_company_default("default_provisional_account")
|
return
|
||||||
if not self.provisional_expense_account:
|
|
||||||
self.provisional_expense_account = default_provisional_account
|
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):
|
def validate_with_previous_doc(self):
|
||||||
super(PurchaseReceipt, self).validate_with_previous_doc(
|
super(PurchaseReceipt, self).validate_with_previous_doc(
|
||||||
@@ -466,7 +469,9 @@ class PurchaseReceipt(BuyingController):
|
|||||||
and flt(d.qty)
|
and flt(d.qty)
|
||||||
and provisional_accounting_for_non_stock_items
|
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:
|
if warehouse_with_no_account:
|
||||||
frappe.msgprint(
|
frappe.msgprint(
|
||||||
@@ -475,9 +480,10 @@ class PurchaseReceipt(BuyingController):
|
|||||||
+ "\n".join(warehouse_with_no_account)
|
+ "\n".join(warehouse_with_no_account)
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_provisional_gl_entry(self, item, gl_entries, posting_date, reverse=0):
|
def add_provisional_gl_entry(
|
||||||
provisional_expense_account = self.get("provisional_expense_account")
|
self, item, gl_entries, posting_date, provisional_account, reverse=0
|
||||||
credit_currency = get_account_currency(provisional_expense_account)
|
):
|
||||||
|
credit_currency = get_account_currency(provisional_account)
|
||||||
debit_currency = get_account_currency(item.expense_account)
|
debit_currency = get_account_currency(item.expense_account)
|
||||||
expense_account = item.expense_account
|
expense_account = item.expense_account
|
||||||
remarks = self.get("remarks") or _("Accounting Entry for Service")
|
remarks = self.get("remarks") or _("Accounting Entry for Service")
|
||||||
@@ -491,7 +497,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
|
|
||||||
self.add_gl_entry(
|
self.add_gl_entry(
|
||||||
gl_entries=gl_entries,
|
gl_entries=gl_entries,
|
||||||
account=provisional_expense_account,
|
account=provisional_account,
|
||||||
cost_center=item.cost_center,
|
cost_center=item.cost_center,
|
||||||
debit=0.0,
|
debit=0.0,
|
||||||
credit=multiplication_factor * item.amount,
|
credit=multiplication_factor * item.amount,
|
||||||
@@ -511,7 +517,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
debit=multiplication_factor * item.amount,
|
debit=multiplication_factor * item.amount,
|
||||||
credit=0.0,
|
credit=0.0,
|
||||||
remarks=remarks,
|
remarks=remarks,
|
||||||
against_account=provisional_expense_account,
|
against_account=provisional_account,
|
||||||
account_currency=debit_currency,
|
account_currency=debit_currency,
|
||||||
project=item.project,
|
project=item.project,
|
||||||
voucher_detail_no=item.name,
|
voucher_detail_no=item.name,
|
||||||
|
|||||||
@@ -96,7 +96,6 @@
|
|||||||
"include_exploded_items",
|
"include_exploded_items",
|
||||||
"batch_no",
|
"batch_no",
|
||||||
"rejected_serial_no",
|
"rejected_serial_no",
|
||||||
"expense_account",
|
|
||||||
"item_tax_rate",
|
"item_tax_rate",
|
||||||
"item_weight_details",
|
"item_weight_details",
|
||||||
"weight_per_unit",
|
"weight_per_unit",
|
||||||
@@ -107,6 +106,10 @@
|
|||||||
"manufacturer",
|
"manufacturer",
|
||||||
"column_break_16",
|
"column_break_16",
|
||||||
"manufacturer_part_no",
|
"manufacturer_part_no",
|
||||||
|
"accounting_details_section",
|
||||||
|
"expense_account",
|
||||||
|
"column_break_102",
|
||||||
|
"provisional_expense_account",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"project",
|
"project",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
@@ -971,12 +974,27 @@
|
|||||||
"label": "Product Bundle",
|
"label": "Product Bundle",
|
||||||
"options": "Product Bundle",
|
"options": "Product Bundle",
|
||||||
"read_only": 1
|
"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,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-02-01 11:32:27.980524",
|
"modified": "2022-04-11 13:07:32.061402",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt Item",
|
"name": "Purchase Receipt Item",
|
||||||
|
|||||||
@@ -4,15 +4,12 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
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 frappe.utils.user import get_users_with_role
|
||||||
from rq.timeouts import JobTimeoutException
|
from rq.timeouts import JobTimeoutException
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.accounts.utils import (
|
from erpnext.accounts.utils import update_gl_entries_after
|
||||||
check_if_stock_and_account_balance_synced,
|
|
||||||
update_gl_entries_after,
|
|
||||||
)
|
|
||||||
from erpnext.stock.stock_ledger import get_items_to_be_repost, repost_future_sle
|
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():
|
def repost_entries():
|
||||||
|
"""
|
||||||
|
Reposts 'Repost Item Valuation' entries in queue.
|
||||||
|
Called hourly via hooks.py.
|
||||||
|
"""
|
||||||
if not in_configured_timeslot():
|
if not in_configured_timeslot():
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -239,9 +240,6 @@ def repost_entries():
|
|||||||
if riv_entries:
|
if riv_entries:
|
||||||
return
|
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():
|
def get_repost_item_valuation_entries():
|
||||||
return frappe.db.sql(
|
return frappe.db.sql(
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ def get_basic_details(args, item, overwrite_warehouse=True):
|
|||||||
"expense_account": expense_account
|
"expense_account": expense_account
|
||||||
or get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults),
|
or get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults),
|
||||||
"discount_account": get_default_discount_account(args, item_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(
|
"cost_center": get_default_cost_center(
|
||||||
args, item_defaults, item_group_defaults, brand_defaults
|
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):
|
def get_default_discount_account(args, item):
|
||||||
return item.get("default_discount_account") or args.discount_account
|
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 Reports,Rapports d'évaluation,
|
||||||
Assessment Result,Résultat de l'Évaluation,
|
Assessment Result,Résultat de l'Évaluation,
|
||||||
Assessment Result record {0} already exists.,Le Résultat d'Évaluation {0} existe déjà.,
|
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,Catégorie d'Actif,
|
||||||
Asset Category is mandatory for Fixed Asset item,Catégorie d'Actif est obligatoire pour l'article Immobilisé,
|
Asset Category is mandatory for Fixed Asset item,Catégorie d'Actif est obligatoire pour l'article Immobilisé,
|
||||||
Asset Maintenance,Maintenance des actifs,
|
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 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 Datetime,À la Date,
|
||||||
To Deliver,À Livrer,
|
To Deliver,À Livrer,
|
||||||
|
{} To Deliver,{} à livrer
|
||||||
To Deliver and Bill,À Livrer et Facturer,
|
To Deliver and Bill,À Livrer et Facturer,
|
||||||
To Fiscal Year,À l'année fiscale,
|
To Fiscal Year,À l'année fiscale,
|
||||||
To GSTIN,GSTIN (Destination),
|
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
|
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
|
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"
|
"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