mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-09 23:39:28 +00:00
Compare commits
1 Commits
v14.75.2
...
mergify/bp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b3e1a1747 |
@@ -3,7 +3,7 @@ import inspect
|
||||
|
||||
import frappe
|
||||
|
||||
__version__ = "14.75.2"
|
||||
__version__ = "14.67.1"
|
||||
|
||||
|
||||
def get_default_company(user=None):
|
||||
|
||||
@@ -58,7 +58,7 @@ def build_conditions(process_type, account, company):
|
||||
)
|
||||
|
||||
if account:
|
||||
conditions += f"AND {deferred_account}={frappe.db.escape(account)}"
|
||||
conditions += f"AND {deferred_account}='{account}'"
|
||||
elif company:
|
||||
conditions += f"AND p.company = {frappe.db.escape(company)}"
|
||||
|
||||
|
||||
@@ -224,6 +224,11 @@
|
||||
"link_doctype": "Bank Guarantee",
|
||||
"link_fieldname": "bank_account"
|
||||
},
|
||||
{
|
||||
"group": "Transactions",
|
||||
"link_doctype": "Payroll Entry",
|
||||
"link_fieldname": "bank_account"
|
||||
},
|
||||
{
|
||||
"group": "Transactions",
|
||||
"link_doctype": "Bank Transaction",
|
||||
@@ -250,7 +255,7 @@
|
||||
"link_fieldname": "default_bank_account"
|
||||
}
|
||||
],
|
||||
"modified": "2024-10-30 09:41:14.113414",
|
||||
"modified": "2024-09-24 06:57:41.292970",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Account",
|
||||
|
||||
@@ -55,7 +55,7 @@ class BankClearance(Document):
|
||||
"Payment Entry" as payment_document, name as payment_entry,
|
||||
reference_no as cheque_number, reference_date as cheque_date,
|
||||
if(paid_from=%(account)s, paid_amount + total_taxes_and_charges, 0) as credit,
|
||||
if(paid_from=%(account)s, 0, received_amount + total_taxes_and_charges) as debit,
|
||||
if(paid_from=%(account)s, 0, received_amount) as debit,
|
||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||
from `tabPayment Entry`
|
||||
|
||||
@@ -153,7 +153,7 @@ class JournalEntry(AccountsController):
|
||||
frappe.throw(_("Journal Entry type should be set as Depreciation Entry for asset depreciation"))
|
||||
|
||||
def validate_stock_accounts(self):
|
||||
stock_accounts = get_stock_accounts(self.company, accounts=self.accounts)
|
||||
stock_accounts = get_stock_accounts(self.company, self.doctype, self.name)
|
||||
for account in stock_accounts:
|
||||
account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
|
||||
account, self.posting_date, self.company
|
||||
|
||||
@@ -146,12 +146,12 @@ class TestJournalEntry(unittest.TestCase):
|
||||
"credit_in_account_currency": 0 if diff > 0 else abs(diff),
|
||||
},
|
||||
)
|
||||
jv.insert()
|
||||
|
||||
if account_bal == stock_bal:
|
||||
self.assertRaises(StockAccountInvalidTransaction, jv.insert)
|
||||
self.assertRaises(StockAccountInvalidTransaction, jv.submit)
|
||||
frappe.db.rollback()
|
||||
else:
|
||||
jv.insert()
|
||||
jv.submit()
|
||||
jv.cancel()
|
||||
|
||||
|
||||
@@ -2270,9 +2270,7 @@ def get_party_details(company, party_type, party, date, cost_center=None):
|
||||
account_balance = get_balance_on(party_account, date, cost_center=cost_center)
|
||||
_party_name = "title" if party_type == "Shareholder" else party_type.lower() + "_name"
|
||||
party_name = frappe.db.get_value(party_type, party, _party_name)
|
||||
party_balance = get_balance_on(
|
||||
party_type=party_type, party=party, company=company, cost_center=cost_center
|
||||
)
|
||||
party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center)
|
||||
if party_type in ["Customer", "Supplier"]:
|
||||
bank_account = get_party_bank_account(party_type, party)
|
||||
|
||||
|
||||
@@ -256,7 +256,6 @@ class PaymentReconciliation(Document):
|
||||
"posting_date": inv.posting_date,
|
||||
"currency": inv.currency,
|
||||
"cost_center": inv.cost_center,
|
||||
"remarks": inv.remarks,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"amount",
|
||||
"difference_amount",
|
||||
"sec_break1",
|
||||
"remarks",
|
||||
"remark",
|
||||
"currency",
|
||||
"exchange_rate",
|
||||
"cost_center"
|
||||
@@ -74,6 +74,12 @@
|
||||
"fieldname": "sec_break1",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "remark",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Remark",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
@@ -99,18 +105,12 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"options": "Cost Center"
|
||||
},
|
||||
{
|
||||
"fieldname": "remarks",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Remarks",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"is_virtual": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-10-29 16:24:43.021230",
|
||||
"modified": "2023-11-17 17:33:34.818530",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Reconciliation Payment",
|
||||
|
||||
@@ -238,12 +238,12 @@ class PaymentRequest(Document):
|
||||
return controller.get_payment_url(
|
||||
**{
|
||||
"amount": flt(self.grand_total, self.precision("grand_total")),
|
||||
"title": data.company,
|
||||
"description": self.subject,
|
||||
"title": data.company.encode("utf-8"),
|
||||
"description": self.subject.encode("utf-8"),
|
||||
"reference_doctype": "Payment Request",
|
||||
"reference_docname": self.name,
|
||||
"payer_email": self.email_to or frappe.session.user,
|
||||
"payer_name": data.customer_name,
|
||||
"payer_name": frappe.safe_encode(data.customer_name),
|
||||
"order_id": self.name,
|
||||
"currency": self.currency,
|
||||
}
|
||||
|
||||
@@ -80,10 +80,8 @@ frappe.ui.form.on("POS Closing Entry", {
|
||||
) {
|
||||
reset_values(frm);
|
||||
frappe.run_serially([
|
||||
() => frappe.dom.freeze(__("Loading Invoices! Please Wait...")),
|
||||
() => frm.trigger("set_opening_amounts"),
|
||||
() => frm.trigger("get_pos_invoices"),
|
||||
() => frappe.dom.unfreeze(),
|
||||
]);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -389,9 +389,7 @@ def split_invoices(invoices):
|
||||
if not item.serial_no:
|
||||
continue
|
||||
|
||||
return_against_is_added = any(
|
||||
d for d in _invoices if d and d[0].pos_invoice == pos_invoice.return_against
|
||||
)
|
||||
return_against_is_added = any(d for d in _invoices if d.pos_invoice == pos_invoice.return_against)
|
||||
if return_against_is_added:
|
||||
break
|
||||
|
||||
|
||||
@@ -715,11 +715,14 @@ def get_pricing_rule_items(pr_doc, other_items=False) -> list:
|
||||
|
||||
def validate_coupon_code(coupon_name):
|
||||
coupon = frappe.get_doc("Coupon Code", coupon_name)
|
||||
if coupon.valid_from and coupon.valid_from > getdate(today()):
|
||||
frappe.throw(_("Sorry, this coupon code's validity has not started"))
|
||||
elif coupon.valid_upto and coupon.valid_upto < getdate(today()):
|
||||
frappe.throw(_("Sorry, this coupon code's validity has expired"))
|
||||
elif coupon.maximum_use and coupon.used >= coupon.maximum_use:
|
||||
|
||||
if coupon.valid_from:
|
||||
if coupon.valid_from > getdate(today()):
|
||||
frappe.throw(_("Sorry, this coupon code's validity has not started"))
|
||||
elif coupon.valid_upto:
|
||||
if coupon.valid_upto < getdate(today()):
|
||||
frappe.throw(_("Sorry, this coupon code's validity has expired"))
|
||||
elif coupon.used >= coupon.maximum_use:
|
||||
frappe.throw(_("Sorry, this coupon code is no longer valid"))
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"payment_terms_template",
|
||||
"sales_partner",
|
||||
"sales_person",
|
||||
"show_remarks",
|
||||
"based_on_payment_terms",
|
||||
"section_break_3",
|
||||
"customer_collection",
|
||||
@@ -389,16 +388,10 @@
|
||||
"fieldname": "ignore_cr_dr_notes",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore System Generated Credit / Debit Notes"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "show_remarks",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Remarks"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2024-10-18 17:51:39.108481",
|
||||
"modified": "2024-08-13 10:41:18.381165",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Process Statement Of Accounts",
|
||||
|
||||
@@ -132,7 +132,6 @@ def get_common_filters(doc):
|
||||
"finance_book": doc.finance_book if doc.finance_book else None,
|
||||
"account": [doc.account] if doc.account else None,
|
||||
"cost_center": [cc.cost_center_name for cc in doc.cost_center],
|
||||
"show_remarks": doc.show_remarks,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -25,13 +25,6 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
this.frm.set_query("expense_account", "items", function () {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.get_expense_account",
|
||||
filters: { company: doc.company },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
onload() {
|
||||
@@ -310,11 +303,8 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
|
||||
party_type: "Supplier",
|
||||
account: this.frm.doc.credit_to,
|
||||
price_list: this.frm.doc.buying_price_list,
|
||||
fetch_payment_terms_template: cint(
|
||||
(this.frm.doc.is_return == 0) & !this.frm.doc.ignore_default_payment_terms_template
|
||||
),
|
||||
},
|
||||
function () {
|
||||
fetch_payment_terms_template: cint(!this.frm.doc.ignore_default_payment_terms_template)
|
||||
}, function() {
|
||||
me.apply_pricing_rule();
|
||||
me.frm.doc.apply_tds = me.frm.supplier_tds ? 1 : 0;
|
||||
me.frm.doc.tax_withholding_category = me.frm.supplier_tds;
|
||||
@@ -479,6 +469,13 @@ cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn)
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.set_query("expense_account", "items", function(doc) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.get_expense_account",
|
||||
filters: {'company': doc.company }
|
||||
}
|
||||
});
|
||||
|
||||
cur_frm.set_query("wip_composite_asset", "items", function() {
|
||||
return {
|
||||
filters: {'is_composite_asset': 1, 'docstatus': 0 }
|
||||
|
||||
@@ -1128,14 +1128,12 @@
|
||||
"label": "Payment Terms"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(!doc.is_paid && !doc.is_return)",
|
||||
"fieldname": "payment_terms_template",
|
||||
"fieldtype": "Link",
|
||||
"label": "Payment Terms Template",
|
||||
"options": "Payment Terms Template"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(!doc.is_paid && !doc.is_return)",
|
||||
"fieldname": "payment_schedule",
|
||||
"fieldtype": "Table",
|
||||
"label": "Payment Schedule",
|
||||
@@ -1613,7 +1611,7 @@
|
||||
"idx": 204,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2024-10-25 18:13:01.944477",
|
||||
"modified": "2024-09-11 12:59:19.130593",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
||||
@@ -280,12 +280,8 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
|
||||
party_type: "Customer",
|
||||
account: this.frm.doc.debit_to,
|
||||
price_list: this.frm.doc.selling_price_list,
|
||||
pos_profile: pos_profile,
|
||||
fetch_payment_terms_template: cint(
|
||||
(this.frm.doc.is_return == 0) & !this.frm.doc.ignore_default_payment_terms_template
|
||||
),
|
||||
},
|
||||
function () {
|
||||
pos_profile: pos_profile
|
||||
}, function() {
|
||||
me.apply_pricing_rule();
|
||||
});
|
||||
|
||||
|
||||
@@ -482,7 +482,7 @@ def get_tds_amount(ldc, parties, inv, tax_details, vouchers):
|
||||
payment_entry_filters.pop("apply_tax_withholding_amount", None)
|
||||
payment_entry_filters.pop("tax_withholding_category", None)
|
||||
|
||||
supp_inv_credit_amt = frappe.db.get_value("Purchase Invoice", invoice_filters, field) or 0.0
|
||||
supp_credit_amt = frappe.db.get_value("Purchase Invoice", invoice_filters, field) or 0.0
|
||||
|
||||
supp_jv_credit_amt = (
|
||||
frappe.db.get_value(
|
||||
@@ -506,7 +506,7 @@ def get_tds_amount(ldc, parties, inv, tax_details, vouchers):
|
||||
group_by="payment_type",
|
||||
)
|
||||
|
||||
supp_credit_amt = supp_jv_credit_amt
|
||||
supp_credit_amt += supp_jv_credit_amt
|
||||
supp_credit_amt += inv.tax_withholding_net_total
|
||||
|
||||
for type in payment_entry_amounts:
|
||||
@@ -524,18 +524,18 @@ def get_tds_amount(ldc, parties, inv, tax_details, vouchers):
|
||||
tax_withholding_net_total = inv.tax_withholding_net_total
|
||||
|
||||
if (threshold and tax_withholding_net_total >= threshold) or (
|
||||
cumulative_threshold and (supp_credit_amt + supp_inv_credit_amt) >= cumulative_threshold
|
||||
cumulative_threshold and supp_credit_amt >= cumulative_threshold
|
||||
):
|
||||
# Get net total again as TDS is calculated on net total
|
||||
# Grand is used to just check for threshold breach
|
||||
net_total = (
|
||||
frappe.db.get_value("Purchase Invoice", invoice_filters, "sum(tax_withholding_net_total)") or 0.0
|
||||
)
|
||||
supp_credit_amt += net_total
|
||||
|
||||
if (cumulative_threshold and supp_credit_amt >= cumulative_threshold) and cint(
|
||||
tax_details.tax_on_excess_amount
|
||||
):
|
||||
# Get net total again as TDS is calculated on net total
|
||||
# Grand is used to just check for threshold breach
|
||||
net_total = (
|
||||
frappe.db.get_value("Purchase Invoice", invoice_filters, "sum(tax_withholding_net_total)")
|
||||
or 0.0
|
||||
)
|
||||
net_total += inv.tax_withholding_net_total
|
||||
supp_credit_amt = net_total - cumulative_threshold
|
||||
|
||||
if ldc and is_valid_certificate(ldc, inv.get("posting_date") or inv.get("transaction_date"), 0):
|
||||
|
||||
@@ -121,46 +121,6 @@ class TestTaxWithholdingCategory(FrappeTestCase):
|
||||
for d in reversed(invoices):
|
||||
d.cancel()
|
||||
|
||||
def test_cumulative_threshold_with_party_ledger_amount_on_net_total(self):
|
||||
invoices = []
|
||||
frappe.db.set_value(
|
||||
"Supplier", "Test TDS Supplier3", "tax_withholding_category", "Advance TDS Category"
|
||||
)
|
||||
|
||||
# Invoice with tax and without exceeding single and cumulative thresholds
|
||||
for _ in range(2):
|
||||
pi = create_purchase_invoice(supplier="Test TDS Supplier3", rate=1000, do_not_save=True)
|
||||
pi.apply_tds = 1
|
||||
pi.append(
|
||||
"taxes",
|
||||
{
|
||||
"category": "Total",
|
||||
"charge_type": "Actual",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"cost_center": "Main - _TC",
|
||||
"tax_amount": 500,
|
||||
"description": "Test",
|
||||
"add_deduct_tax": "Add",
|
||||
},
|
||||
)
|
||||
pi.save()
|
||||
pi.submit()
|
||||
invoices.append(pi)
|
||||
|
||||
# Third Invoice exceeds single threshold and not exceeding cumulative threshold
|
||||
pi1 = create_purchase_invoice(supplier="Test TDS Supplier3", rate=6000)
|
||||
pi1.apply_tds = 1
|
||||
pi1.save()
|
||||
pi1.submit()
|
||||
invoices.append(pi1)
|
||||
|
||||
# Cumulative threshold is 10,000
|
||||
# Threshold calculation should be only on the third invoice
|
||||
self.assertEqual(pi1.taxes[0].tax_amount, 800)
|
||||
|
||||
for d in reversed(invoices):
|
||||
d.cancel()
|
||||
|
||||
def test_cumulative_threshold_tcs(self):
|
||||
frappe.db.set_value(
|
||||
"Customer", "Test TCS Customer", "tax_withholding_category", "Cumulative Threshold TCS"
|
||||
|
||||
@@ -500,8 +500,7 @@ class ReceivablePayableReport:
|
||||
from `tab{row.voucher_type}` si, `tabPayment Schedule` ps
|
||||
where
|
||||
si.name = ps.parent and
|
||||
si.name = %s and
|
||||
si.is_return = 0
|
||||
si.name = %s
|
||||
order by ps.paid_amount desc, due_date
|
||||
""",
|
||||
row.voucher_no,
|
||||
|
||||
@@ -122,24 +122,21 @@ class Deferred_Item:
|
||||
"""
|
||||
simulate future posting by creating dummy gl entries. starts from the last posting date.
|
||||
"""
|
||||
if (
|
||||
self.service_start_date != self.service_end_date
|
||||
and add_days(self.last_entry_date, 1) < self.service_end_date
|
||||
):
|
||||
self.estimate_for_period_list = get_period_list(
|
||||
self.filters.from_fiscal_year,
|
||||
self.filters.to_fiscal_year,
|
||||
add_days(self.last_entry_date, 1),
|
||||
self.service_end_date,
|
||||
"Date Range",
|
||||
"Monthly",
|
||||
company=self.filters.company,
|
||||
)
|
||||
|
||||
for period in self.estimate_for_period_list:
|
||||
amount = self.calculate_amount(period.from_date, period.to_date)
|
||||
gle = self.make_dummy_gle(period.key, period.to_date, amount)
|
||||
self.gle_entries.append(gle)
|
||||
if self.service_start_date != self.service_end_date:
|
||||
if add_days(self.last_entry_date, 1) < self.period_list[-1].to_date:
|
||||
self.estimate_for_period_list = get_period_list(
|
||||
self.filters.from_fiscal_year,
|
||||
self.filters.to_fiscal_year,
|
||||
add_days(self.last_entry_date, 1),
|
||||
self.period_list[-1].to_date,
|
||||
"Date Range",
|
||||
"Monthly",
|
||||
company=self.filters.company,
|
||||
)
|
||||
for period in self.estimate_for_period_list:
|
||||
amount = self.calculate_amount(period.from_date, period.to_date)
|
||||
gle = self.make_dummy_gle(period.key, period.to_date, amount)
|
||||
self.gle_entries.append(gle)
|
||||
|
||||
def calculate_item_revenue_expense_for_period(self):
|
||||
"""
|
||||
|
||||
@@ -337,17 +337,9 @@ def get_accounts_with_children(accounts):
|
||||
return list(set(all_accounts)) if all_accounts else None
|
||||
|
||||
|
||||
def set_bill_no(gl_entries):
|
||||
inv_details = get_supplier_invoice_details()
|
||||
for gl in gl_entries:
|
||||
gl["bill_no"] = inv_details.get(gl.get("against_voucher"), "")
|
||||
|
||||
|
||||
def get_data_with_opening_closing(filters, account_details, accounting_dimensions, gl_entries):
|
||||
data = []
|
||||
|
||||
set_bill_no(gl_entries)
|
||||
|
||||
gle_map = initialize_gle_map(gl_entries, filters)
|
||||
|
||||
totals, entries = get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map)
|
||||
@@ -521,6 +513,7 @@ def get_account_type_map(company):
|
||||
|
||||
def get_result_as_list(data, filters):
|
||||
balance, _balance_in_account_currency = 0, 0
|
||||
inv_details = get_supplier_invoice_details()
|
||||
|
||||
for d in data:
|
||||
if not d.get("posting_date"):
|
||||
@@ -530,6 +523,7 @@ def get_result_as_list(data, filters):
|
||||
d["balance"] = balance
|
||||
|
||||
d["account_currency"] = filters.account_currency
|
||||
d["bill_no"] = inv_details.get(d.get("against_voucher"), "")
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@@ -522,8 +522,7 @@ def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts, inclu
|
||||
tax_details = frappe.db.sql(
|
||||
"""select parent, account_head,
|
||||
sum(base_tax_amount_after_discount_amount) as tax_amount
|
||||
from `tabSales Taxes and Charges` where parent in (%s) and parenttype = 'Sales Invoice'
|
||||
group by parent, account_head"""
|
||||
from `tabSales Taxes and Charges` where parent in (%s) group by parent, account_head"""
|
||||
% ", ".join(["%s"] * len(invoice_list)),
|
||||
tuple(inv.name for inv in invoice_list),
|
||||
as_dict=1,
|
||||
|
||||
@@ -1524,16 +1524,12 @@ def compare_existing_and_expected_gle(existing_gle, expected_gle, precision):
|
||||
return matched
|
||||
|
||||
|
||||
def get_stock_accounts(company, voucher_type=None, voucher_no=None, accounts=None):
|
||||
def get_stock_accounts(company, voucher_type=None, voucher_no=None):
|
||||
stock_accounts = [
|
||||
d.name
|
||||
for d in frappe.db.get_all("Account", {"account_type": "Stock", "company": company, "is_group": 0})
|
||||
]
|
||||
|
||||
if accounts:
|
||||
stock_accounts = [row.account for row in accounts if row.account in stock_accounts]
|
||||
|
||||
elif voucher_type and voucher_no:
|
||||
if voucher_type and voucher_no:
|
||||
if voucher_type == "Journal Entry":
|
||||
stock_accounts = [
|
||||
d.account
|
||||
@@ -1930,7 +1926,6 @@ class QueryPaymentLedger:
|
||||
ple.cost_center.as_("cost_center"),
|
||||
Sum(ple.amount).as_("amount"),
|
||||
Sum(ple.amount_in_account_currency).as_("amount_in_account_currency"),
|
||||
ple.remarks,
|
||||
)
|
||||
.where(ple.delinked == 0)
|
||||
.where(Criterion.all(filter_on_voucher_no))
|
||||
@@ -1993,7 +1988,6 @@ class QueryPaymentLedger:
|
||||
Table("vouchers").due_date,
|
||||
Table("vouchers").currency,
|
||||
Table("vouchers").cost_center.as_("cost_center"),
|
||||
Table("vouchers").remarks,
|
||||
)
|
||||
.where(Criterion.all(filter_on_outstanding_amount))
|
||||
)
|
||||
|
||||
@@ -218,8 +218,19 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends e
|
||||
}
|
||||
if(doc.status != "Closed") {
|
||||
if (doc.status != "On Hold") {
|
||||
<<<<<<< HEAD
|
||||
if(flt(doc.per_received) < 100 && allow_receipt) {
|
||||
cur_frm.add_custom_button(__('Purchase Receipt'), this.make_purchase_receipt, __('Create'));
|
||||
=======
|
||||
if (flt(doc.per_received) < 100 && allow_receipt) {
|
||||
this.frm.add_custom_button(
|
||||
__("Purchase Receipt"),
|
||||
() => {
|
||||
me.make_purchase_receipt();
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
>>>>>>> a671fe13d4 (fix: list view and form status not same for purchase order (#43690))
|
||||
if (doc.is_subcontracted) {
|
||||
if (doc.is_old_subcontracting_flow) {
|
||||
if (me.has_unsupplied_items()) {
|
||||
@@ -231,9 +242,21 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends e
|
||||
}
|
||||
}
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
if(flt(doc.per_billed) < 100)
|
||||
cur_frm.add_custom_button(__('Purchase Invoice'),
|
||||
this.make_purchase_invoice, __('Create'));
|
||||
=======
|
||||
// Please do not add precision in the below flt function
|
||||
if (flt(doc.per_billed) < 100)
|
||||
this.frm.add_custom_button(
|
||||
__("Purchase Invoice"),
|
||||
() => {
|
||||
me.make_purchase_invoice();
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
>>>>>>> a671fe13d4 (fix: list view and form status not same for purchase order (#43690))
|
||||
|
||||
if(flt(doc.per_billed) < 100 && doc.status != "Delivered") {
|
||||
this.frm.add_custom_button(
|
||||
|
||||
@@ -14,26 +14,15 @@ def get_data():
|
||||
"Material Request": ["items", "material_request"],
|
||||
"Supplier Quotation": ["items", "supplier_quotation"],
|
||||
"Project": ["items", "project"],
|
||||
"Sales Order": ["items", "sales_order"],
|
||||
"BOM": ["items", "bom"],
|
||||
"Production Plan": ["items", "production_plan"],
|
||||
"Blanket Order": ["items", "blanket_order"],
|
||||
},
|
||||
"transactions": [
|
||||
{"label": _("Related"), "items": ["Purchase Receipt", "Purchase Invoice", "Sales Order"]},
|
||||
{"label": _("Related"), "items": ["Purchase Receipt", "Purchase Invoice"]},
|
||||
{"label": _("Payment"), "items": ["Payment Entry", "Journal Entry", "Payment Request"]},
|
||||
{
|
||||
"label": _("Reference"),
|
||||
"items": ["Supplier Quotation", "Project", "Auto Repeat"],
|
||||
},
|
||||
{
|
||||
"label": _("Manufacturing"),
|
||||
"items": ["Material Request", "BOM", "Production Plan", "Blanket Order"],
|
||||
},
|
||||
{
|
||||
"label": _("Sub-contracting"),
|
||||
"items": ["Subcontracting Order", "Stock Entry"],
|
||||
"items": ["Material Request", "Supplier Quotation", "Project", "Auto Repeat"],
|
||||
},
|
||||
{"label": _("Sub-contracting"), "items": ["Subcontracting Order", "Stock Entry"]},
|
||||
{"label": _("Internal"), "items": ["Sales Order"]},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -10,14 +10,22 @@ frappe.listview_settings["Purchase Order"] = {
|
||||
"status",
|
||||
],
|
||||
get_indicator: function (doc) {
|
||||
// Please do not add precision in the flt function
|
||||
if (doc.status === "Closed") {
|
||||
return [__("Closed"), "green", "status,=,Closed"];
|
||||
} else if (doc.status === "On Hold") {
|
||||
return [__("On Hold"), "orange", "status,=,On Hold"];
|
||||
} else if (doc.status === "Delivered") {
|
||||
return [__("Delivered"), "green", "status,=,Closed"];
|
||||
<<<<<<< HEAD
|
||||
} else if (flt(doc.per_received, 2) < 100 && doc.status !== "Closed") {
|
||||
if (flt(doc.per_billed, 2) < 100) {
|
||||
=======
|
||||
} else if (doc.advance_payment_status == "Initiated") {
|
||||
return [__("To Pay"), "gray", "advance_payment_status,=,Initiated"];
|
||||
} else if (flt(doc.per_received) < 100 && doc.status !== "Closed") {
|
||||
if (flt(doc.per_billed) < 100) {
|
||||
>>>>>>> a671fe13d4 (fix: list view and form status not same for purchase order (#43690))
|
||||
return [
|
||||
__("To Receive and Bill"),
|
||||
"orange",
|
||||
@@ -26,17 +34,9 @@ frappe.listview_settings["Purchase Order"] = {
|
||||
} else {
|
||||
return [__("To Receive"), "orange", "per_received,<,100|per_billed,=,100|status,!=,Closed"];
|
||||
}
|
||||
} else if (
|
||||
flt(doc.per_received, 2) >= 100 &&
|
||||
flt(doc.per_billed, 2) < 100 &&
|
||||
doc.status !== "Closed"
|
||||
) {
|
||||
} else if (flt(doc.per_received) >= 100 && flt(doc.per_billed) < 100 && doc.status !== "Closed") {
|
||||
return [__("To Bill"), "orange", "per_received,=,100|per_billed,<,100|status,!=,Closed"];
|
||||
} else if (
|
||||
flt(doc.per_received, 2) >= 100 &&
|
||||
flt(doc.per_billed, 2) == 100 &&
|
||||
doc.status !== "Closed"
|
||||
) {
|
||||
} else if (flt(doc.per_received) >= 100 && flt(doc.per_billed) == 100 && doc.status !== "Closed") {
|
||||
return [__("Completed"), "green", "per_received,=,100|per_billed,=,100|status,!=,Closed"];
|
||||
}
|
||||
},
|
||||
|
||||
@@ -137,8 +137,8 @@ frappe.ui.form.on("Request for Quotation",{
|
||||
return;
|
||||
}
|
||||
},
|
||||
__("Download PDF for Supplier"),
|
||||
__("Download")
|
||||
"Download PDF for Supplier",
|
||||
"Download"
|
||||
);
|
||||
},
|
||||
__("Tools")
|
||||
@@ -257,10 +257,8 @@ frappe.ui.form.on("Request for Quotation",{
|
||||
});
|
||||
};
|
||||
|
||||
const msg = __(
|
||||
"This is a preview of the email to be sent. A PDF of the document will automatically be attached with the email."
|
||||
);
|
||||
dialog.fields_dict.note.$wrapper.append(`<p class="small text-muted">${msg}</p>`);
|
||||
dialog.fields_dict.note.$wrapper.append(`<p class="small text-muted">This is a preview of the email to be sent. A PDF of the document will
|
||||
automatically be attached with the email.</p>`);
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@@ -357,15 +357,12 @@ class AccountsController(TransactionBase):
|
||||
def validate_return_against_account(self):
|
||||
if self.doctype in ["Sales Invoice", "Purchase Invoice"] and self.is_return and self.return_against:
|
||||
cr_dr_account_field = "debit_to" if self.doctype == "Sales Invoice" else "credit_to"
|
||||
original_account = frappe.get_value(self.doctype, self.return_against, cr_dr_account_field)
|
||||
if original_account != self.get(cr_dr_account_field):
|
||||
cr_dr_account_label = "Debit To" if self.doctype == "Sales Invoice" else "Credit To"
|
||||
cr_dr_account = self.get(cr_dr_account_field)
|
||||
if frappe.get_value(self.doctype, self.return_against, cr_dr_account_field) != cr_dr_account:
|
||||
frappe.throw(
|
||||
_(
|
||||
"Please set {0} to {1}, the same account that was used in the original invoice {2}."
|
||||
).format(
|
||||
frappe.bold(_(self.meta.get_label(cr_dr_account_field), context=self.doctype)),
|
||||
frappe.bold(original_account),
|
||||
frappe.bold(self.return_against),
|
||||
_("'{0}' account: '{1}' should match the Return Against Invoice").format(
|
||||
frappe.bold(cr_dr_account_label), frappe.bold(cr_dr_account)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -415,11 +412,6 @@ class AccountsController(TransactionBase):
|
||||
)
|
||||
|
||||
def validate_invoice_documents_schedule(self):
|
||||
if self.is_return:
|
||||
self.payment_terms_template = ""
|
||||
self.payment_schedule = []
|
||||
return
|
||||
|
||||
self.validate_payment_schedule_dates()
|
||||
self.set_due_date()
|
||||
self.set_payment_schedule()
|
||||
@@ -434,7 +426,7 @@ class AccountsController(TransactionBase):
|
||||
self.validate_payment_schedule_amount()
|
||||
|
||||
def validate_all_documents_schedule(self):
|
||||
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||
if self.doctype in ("Sales Invoice", "Purchase Invoice") and not self.is_return:
|
||||
self.validate_invoice_documents_schedule()
|
||||
elif self.doctype in ("Quotation", "Purchase Order", "Sales Order"):
|
||||
self.validate_non_invoice_documents_schedule()
|
||||
@@ -3313,9 +3305,6 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
parent.update_billing_percentage()
|
||||
parent.set_status()
|
||||
|
||||
parent.validate_uom_is_integer("uom", "qty")
|
||||
parent.validate_uom_is_integer("stock_uom", "stock_qty")
|
||||
|
||||
|
||||
def check_if_child_table_updated(child_table_before_update, child_table_after_update, fields_to_check):
|
||||
accounting_dimensions = [*get_accounting_dimensions(), "cost_center", "project"]
|
||||
|
||||
@@ -78,9 +78,6 @@ def validate_returned_items(doc):
|
||||
if doc.doctype in ["Purchase Invoice", "Purchase Receipt", "Subcontracting Receipt"]:
|
||||
select_fields += ",rejected_qty, received_qty"
|
||||
|
||||
if doc.doctype in ["Purchase Receipt", "Purchase Invoice"]:
|
||||
select_fields += ",name"
|
||||
|
||||
for d in frappe.db.sql(
|
||||
f"""select {select_fields} from `tab{doc.doctype} Item` where parent = %s""",
|
||||
doc.return_against,
|
||||
@@ -106,24 +103,15 @@ def validate_returned_items(doc):
|
||||
|
||||
items_returned = False
|
||||
for d in doc.get("items"):
|
||||
key = d.item_code
|
||||
raise_exception = False
|
||||
if doc.doctype in ["Purchase Receipt", "Purchase Invoice"]:
|
||||
field = frappe.scrub(doc.doctype) + "_item"
|
||||
if d.get(field):
|
||||
key = (d.item_code, d.get(field))
|
||||
raise_exception = True
|
||||
|
||||
if d.item_code and (flt(d.qty) < 0 or flt(d.get("received_qty")) < 0):
|
||||
if key not in valid_items:
|
||||
frappe.msgprint(
|
||||
if d.item_code not in valid_items:
|
||||
frappe.throw(
|
||||
_("Row # {0}: Returned Item {1} does not exist in {2} {3}").format(
|
||||
d.idx, d.item_code, doc.doctype, doc.return_against
|
||||
),
|
||||
raise_exception=raise_exception,
|
||||
)
|
||||
)
|
||||
else:
|
||||
ref = valid_items.get(key, frappe._dict())
|
||||
ref = valid_items.get(d.item_code, frappe._dict())
|
||||
validate_quantity(doc, d, ref, valid_items, already_returned_items)
|
||||
|
||||
if (
|
||||
@@ -218,12 +206,8 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
||||
def get_ref_item_dict(valid_items, ref_item_row):
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
|
||||
key = ref_item_row.item_code
|
||||
if ref_item_row.get("name"):
|
||||
key = (ref_item_row.item_code, ref_item_row.name)
|
||||
|
||||
valid_items.setdefault(
|
||||
key,
|
||||
ref_item_row.item_code,
|
||||
frappe._dict(
|
||||
{
|
||||
"qty": 0,
|
||||
@@ -237,7 +221,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
}
|
||||
),
|
||||
)
|
||||
item_dict = valid_items[key]
|
||||
item_dict = valid_items[ref_item_row.item_code]
|
||||
item_dict["qty"] += ref_item_row.qty
|
||||
item_dict["stock_qty"] += ref_item_row.get("stock_qty", 0)
|
||||
if ref_item_row.get("rate", 0) > item_dict["rate"]:
|
||||
|
||||
@@ -767,19 +767,26 @@ class JobCard(Document):
|
||||
|
||||
qty = 0
|
||||
if self.work_order:
|
||||
doc = frappe.get_doc("Work Order", self.work_order)
|
||||
if doc.transfer_material_against == "Job Card" and not doc.skip_transfer:
|
||||
min_qty = []
|
||||
completed = True
|
||||
for d in doc.operations:
|
||||
if d.completed_qty:
|
||||
min_qty.append(d.completed_qty)
|
||||
else:
|
||||
min_qty = []
|
||||
if d.status != "Completed":
|
||||
completed = False
|
||||
break
|
||||
|
||||
if min_qty:
|
||||
qty = min(min_qty)
|
||||
if completed:
|
||||
job_cards = frappe.get_all(
|
||||
"Job Card",
|
||||
filters={"work_order": self.work_order, "docstatus": ("!=", 2)},
|
||||
fields="sum(transferred_qty) as qty",
|
||||
group_by="operation_id",
|
||||
)
|
||||
|
||||
doc.db_set("material_transferred_for_manufacturing", qty)
|
||||
if job_cards:
|
||||
qty = min(d.qty for d in job_cards)
|
||||
|
||||
doc.db_set("material_transferred_for_manufacturing", qty)
|
||||
|
||||
self.set_status(update_status)
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ frappe.ui.form.on("Project", {
|
||||
frm.set_query("sales_order", function () {
|
||||
var filters = {
|
||||
project: ["in", frm.doc.__islocal ? [""] : [frm.doc.name, ""]],
|
||||
company: frm.doc.company,
|
||||
};
|
||||
|
||||
if (frm.doc.customer) {
|
||||
|
||||
@@ -15,7 +15,6 @@ def execute(filters=None):
|
||||
filters=filters,
|
||||
fields=[
|
||||
"name",
|
||||
"project_name",
|
||||
"status",
|
||||
"percent_complete",
|
||||
"expected_start_date",
|
||||
@@ -49,11 +48,6 @@ def get_columns():
|
||||
"options": "Project",
|
||||
"width": 200,
|
||||
},
|
||||
{
|
||||
"fieldname": "project_name",
|
||||
"label": _("Project Name"),
|
||||
"width": 200,
|
||||
},
|
||||
{
|
||||
"fieldname": "project_type",
|
||||
"label": _("Type"),
|
||||
@@ -88,7 +82,7 @@ def get_chart_data(data):
|
||||
overdue = []
|
||||
|
||||
for project in data:
|
||||
labels.append(project.project_name)
|
||||
labels.append(project.name)
|
||||
total.append(project.total_tasks)
|
||||
completed.append(project.completed_tasks)
|
||||
overdue.append(project.overdue_tasks)
|
||||
|
||||
@@ -2213,7 +2213,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
payment_terms_template() {
|
||||
var me = this;
|
||||
const doc = this.frm.doc;
|
||||
if(doc.payment_terms_template && doc.doctype !== 'Delivery Note' && doc.is_return == 0) {
|
||||
if(doc.payment_terms_template && doc.doctype !== 'Delivery Note') {
|
||||
var posting_date = doc.posting_date || doc.transaction_date;
|
||||
frappe.call({
|
||||
method: "erpnext.controllers.accounts_controller.get_payment_terms",
|
||||
|
||||
@@ -4,8 +4,7 @@ erpnext.accounts.unreconcile_payment = {
|
||||
add_unreconcile_btn(frm) {
|
||||
if (frm.doc.docstatus == 1) {
|
||||
if (
|
||||
(frm.doc.doctype == "Journal Entry" &&
|
||||
!["Journal Entry", "Bank Entry", "Cash Entry"].includes(frm.doc.voucher_type)) ||
|
||||
(frm.doc.doctype == "Journal Entry" && frm.doc.voucher_type != "Journal Entry") ||
|
||||
!["Purchase Invoice", "Sales Invoice", "Journal Entry", "Payment Entry"].includes(
|
||||
frm.doc.doctype
|
||||
)
|
||||
|
||||
@@ -14,8 +14,6 @@ def get_data():
|
||||
},
|
||||
"internal_links": {
|
||||
"Quotation": ["items", "prevdoc_docname"],
|
||||
"BOM": ["items", "bom_no"],
|
||||
"Blanket Order": ["items", "blanket_order"],
|
||||
},
|
||||
"transactions": [
|
||||
{
|
||||
@@ -24,8 +22,8 @@ def get_data():
|
||||
},
|
||||
{"label": _("Purchasing"), "items": ["Material Request", "Purchase Order"]},
|
||||
{"label": _("Projects"), "items": ["Project"]},
|
||||
{"label": _("Manufacturing"), "items": ["Work Order"]},
|
||||
{"label": _("Reference"), "items": ["Quotation", "Auto Repeat"]},
|
||||
{"label": _("Manufacturing"), "items": ["Work Order", "BOM", "Blanket Order"]},
|
||||
{"label": _("Payment"), "items": ["Payment Entry", "Payment Request", "Journal Entry"]},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -18,21 +18,3 @@ cur_frm.cscript.onload = function () {
|
||||
frappe.ui.form.on("Serial No", "refresh", function (frm) {
|
||||
frm.toggle_enable("item_code", frm.doc.__islocal);
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Serial No", {
|
||||
refresh(frm) {
|
||||
frm.trigger("view_ledgers");
|
||||
},
|
||||
|
||||
view_ledgers(frm) {
|
||||
frm.add_custom_button(__("View Ledgers"), () => {
|
||||
frappe.route_options = {
|
||||
item_code: frm.doc.item_code,
|
||||
serial_no: frm.doc.name,
|
||||
posting_date: frappe.datetime.now_date(),
|
||||
posting_time: frappe.datetime.now_time(),
|
||||
};
|
||||
frappe.set_route("query-report", "Serial No Ledger");
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -335,16 +335,11 @@ def validate_serial_no(sle, item_det):
|
||||
if sr.work_order and work_order and sr.work_order == work_order:
|
||||
allow_existing_serial_no = True
|
||||
|
||||
if (
|
||||
not allow_existing_serial_no
|
||||
and sle.voucher_type
|
||||
in [
|
||||
"Stock Entry",
|
||||
"Purchase Receipt",
|
||||
"Purchase Invoice",
|
||||
]
|
||||
and cint(sle.actual_qty) > 0
|
||||
):
|
||||
if not allow_existing_serial_no and sle.voucher_type in [
|
||||
"Stock Entry",
|
||||
"Purchase Receipt",
|
||||
"Purchase Invoice",
|
||||
]:
|
||||
msg = ""
|
||||
|
||||
if sle.voucher_type == "Stock Entry":
|
||||
|
||||
@@ -714,17 +714,7 @@ frappe.ui.form.on('Stock Entry', {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
frappe.ui.form.on('Stock Entry Detail', {
|
||||
set_basic_rate_manually(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
frm.fields_dict.items.grid.update_docfield_property(
|
||||
"basic_rate",
|
||||
"read_only",
|
||||
row?.set_basic_rate_manually ? 0 : 1
|
||||
);
|
||||
},
|
||||
|
||||
qty: function(frm, cdt, cdn) {
|
||||
frm.events.set_serial_no(frm, cdt, cdn, () => {
|
||||
frm.events.set_basic_rate(frm, cdt, cdn);
|
||||
|
||||
@@ -45,16 +45,8 @@ frappe.query_reports["Serial No Ledger"] = {
|
||||
{
|
||||
label: __("As On Date"),
|
||||
fieldtype: "Date",
|
||||
reqd: 1,
|
||||
fieldname: "posting_date",
|
||||
default: frappe.datetime.get_today(),
|
||||
},
|
||||
{
|
||||
label: __("Posting Time"),
|
||||
fieldtype: "Time",
|
||||
reqd: 1,
|
||||
fieldname: "posting_time",
|
||||
default: frappe.datetime.now_time(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -742,7 +742,7 @@ class update_entries_after:
|
||||
rate = 0
|
||||
# Material Transfer, Repack, Manufacturing
|
||||
if sle.voucher_type == "Stock Entry":
|
||||
self.recalculate_amounts_in_stock_entry(sle.voucher_no, sle.voucher_detail_no)
|
||||
self.recalculate_amounts_in_stock_entry(sle.voucher_no)
|
||||
rate = frappe.db.get_value("Stock Entry Detail", sle.voucher_detail_no, "valuation_rate")
|
||||
# Sales and Purchase Return
|
||||
elif sle.voucher_type in (
|
||||
@@ -853,15 +853,14 @@ class update_entries_after:
|
||||
|
||||
# Update outgoing item's rate, recalculate FG Item's rate and total incoming/outgoing amount
|
||||
if not sle.dependant_sle_voucher_detail_no:
|
||||
self.recalculate_amounts_in_stock_entry(sle.voucher_no, sle.voucher_detail_no)
|
||||
self.recalculate_amounts_in_stock_entry(sle.voucher_no)
|
||||
|
||||
def recalculate_amounts_in_stock_entry(self, voucher_no, voucher_detail_no):
|
||||
def recalculate_amounts_in_stock_entry(self, voucher_no):
|
||||
stock_entry = frappe.get_doc("Stock Entry", voucher_no, for_update=True)
|
||||
stock_entry.calculate_rate_and_amount(reset_outgoing_rate=False, raise_error_if_no_rate=False)
|
||||
stock_entry.db_update()
|
||||
for d in stock_entry.items:
|
||||
if d.name == voucher_detail_no or (not d.s_warehouse and d.t_warehouse):
|
||||
d.db_update()
|
||||
d.db_update()
|
||||
|
||||
def update_rate_on_delivery_and_sales_return(self, sle, outgoing_rate):
|
||||
# Update item's incoming rate on transaction
|
||||
|
||||
@@ -51,7 +51,7 @@ def get_tasks(project, start=0, search=None, item_status=None):
|
||||
"parent_task",
|
||||
],
|
||||
limit_start=start,
|
||||
limit_page_length=100,
|
||||
limit_page_length=10,
|
||||
)
|
||||
task_nest = []
|
||||
for task in tasks:
|
||||
|
||||
@@ -5268,7 +5268,6 @@ Request for Quotation Supplier,Angebotsanfrage Lieferant,
|
||||
Send Email,E-Mail absenden,
|
||||
Quote Status,Zitat Status,
|
||||
Download PDF,PDF Herunterladen,
|
||||
Download PDF for Supplier,PDF für Lieferanten herunterladen,
|
||||
Supplier of Goods or Services.,Lieferant von Waren oder Dienstleistungen.,
|
||||
Name and Type,Name und Typ,
|
||||
SUP-.YYYY.-,SUP-.YYYY.-,
|
||||
@@ -6625,7 +6624,6 @@ This is a location where operations are executed.,"Dies ist ein Ort, an dem Oper
|
||||
This is a location where final product stored.,"Dies ist ein Ort, an dem das Endprodukt gelagert wird.",
|
||||
Scrap Warehouse,Ausschusslager,
|
||||
This is a location where scraped materials are stored.,"Dies ist ein Ort, an dem abgekratzte Materialien gelagert werden.",
|
||||
This is a preview of the email to be sent. A PDF of the document will automatically be attached with the email.,Dies ist eine Vorschau der zu sendenden E-Mail. Ein PDF des Dokuments wird automatisch an die E-Mail angehängt.,
|
||||
Required Items,Erforderliche Elemente,
|
||||
Actual Start Date,Tatsächliches Startdatum,
|
||||
Planned End Date,Geplantes Enddatum,
|
||||
|
||||
|
Can't render this file because it is too large.
|
Reference in New Issue
Block a user