Merge branch 'develop' of https://github.com/aerele/erpnext into ledger-summary-report

This commit is contained in:
Sugesh393
2024-12-05 21:34:36 +05:30
56 changed files with 111494 additions and 97 deletions

View File

@@ -0,0 +1,34 @@
import json
from pathlib import Path
syscohada_countries = [
"bj", # Bénin
"bf", # Burkina-Faso
"cm", # Cameroun
"cf", # Centrafrique
"ci", # Côte d'Ivoire
"cg", # Congo
"km", # Comores
"ga", # Gabon
"gn", # Guinée
"gw", # Guinée-Bissau
"gq", # Guinée Equatoriale
"ml", # Mali
"ne", # Niger
"cd", # République Démocratique du Congo
"sn", # Sénégal
"td", # Tchad
"tg", # Togo
]
folder = Path(__file__).parent
generic_charts = Path(folder).glob("syscohada*.json")
for file in generic_charts:
with open(file) as f:
chart = json.load(f)
for country in syscohada_countries:
chart["country_code"] = country
json_object = json.dumps(chart, indent=4)
with open(Path(folder, file.name.replace("syscohada", country)), "w") as outfile:
outfile.write(json_object)

View File

@@ -127,9 +127,6 @@ class JournalEntry(AccountsController):
self.set_amounts_in_company_currency() self.set_amounts_in_company_currency()
self.validate_debit_credit_amount() self.validate_debit_credit_amount()
self.set_total_debit_credit() self.set_total_debit_credit()
# Do not validate while importing via data import
if not frappe.flags.in_import:
self.validate_total_debit_and_credit()
if not frappe.flags.is_reverse_depr_entry: if not frappe.flags.is_reverse_depr_entry:
self.validate_against_jv() self.validate_against_jv()
@@ -184,6 +181,11 @@ class JournalEntry(AccountsController):
else: else:
return self._cancel() return self._cancel()
def before_submit(self):
# Do not validate while importing via data import
if not frappe.flags.in_import:
self.validate_total_debit_and_credit()
def on_submit(self): def on_submit(self):
self.validate_cheque_info() self.validate_cheque_info()
self.check_credit_limit() self.check_credit_limit()

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: info@erpnext.com\n" "Report-Msgid-Bugs-To: info@erpnext.com\n"
"POT-Creation-Date: 2024-12-01 09:35+0000\n" "POT-Creation-Date: 2024-12-01 09:35+0000\n"
"PO-Revision-Date: 2024-12-02 11:56\n" "PO-Revision-Date: 2024-12-04 14:18\n"
"Last-Translator: info@erpnext.com\n" "Last-Translator: info@erpnext.com\n"
"Language-Team: Persian\n" "Language-Team: Persian\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -3331,7 +3331,7 @@ msgstr "پیش پرداخت"
#. Name of a DocType #. Name of a DocType
#: erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.json #: erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.json
msgid "Advance Payment Ledger Entry" msgid "Advance Payment Ledger Entry"
msgstr "" msgstr "ثبت دفتر پیش پرداخت"
#. Label of the advance_payment_status (Select) field in DocType 'Purchase #. Label of the advance_payment_status (Select) field in DocType 'Purchase
#. Order' #. Order'
@@ -3811,7 +3811,7 @@ msgstr "همه سرنخ (باز)"
#: erpnext/accounts/report/general_ledger/general_ledger.html:68 #: erpnext/accounts/report/general_ledger/general_ledger.html:68
msgid "All Parties " msgid "All Parties "
msgstr "" msgstr "همه طرف‌ها "
#. Option for the 'Send To' (Select) field in DocType 'SMS Center' #. Option for the 'Send To' (Select) field in DocType 'SMS Center'
#: erpnext/selling/doctype/sms_center/sms_center.json #: erpnext/selling/doctype/sms_center/sms_center.json
@@ -4259,7 +4259,7 @@ msgstr "اجازه نرخ صفر"
#: erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json #: erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
#: erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json #: erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
msgid "Allow Zero Valuation Rate" msgid "Allow Zero Valuation Rate"
msgstr "نرخ ارزش گذاری صفر را مجاز کنید" msgstr "نرخ ارزش گذاری صفر مجاز است"
#. Description of the 'Allow Continuous Material Consumption' (Check) field in #. Description of the 'Allow Continuous Material Consumption' (Check) field in
#. DocType 'Manufacturing Settings' #. DocType 'Manufacturing Settings'
@@ -12503,7 +12503,7 @@ msgstr "هزینه شرکت (CTC)"
#. Title of an incoterm #. Title of an incoterm
#: erpnext/setup/doctype/incoterm/incoterms.csv:9 #: erpnext/setup/doctype/incoterm/incoterms.csv:9
msgid "Cost, Insurance and Freight" msgid "Cost, Insurance and Freight"
msgstr "" msgstr "هزینه، بیمه و حمل و نقل"
#. Label of the costing (Tab Break) field in DocType 'BOM' #. Label of the costing (Tab Break) field in DocType 'BOM'
#. Label of the currency_detail (Section Break) field in DocType 'BOM Creator' #. Label of the currency_detail (Section Break) field in DocType 'BOM Creator'
@@ -12870,7 +12870,7 @@ msgstr "ایجاد کارت کار بر اساس اندازه دسته ای"
#: erpnext/accounts/doctype/payment_order/payment_order.js:39 #: erpnext/accounts/doctype/payment_order/payment_order.js:39
msgid "Create Journal Entries" msgid "Create Journal Entries"
msgstr "" msgstr "ایجاد ثبت دفتر روزنامه"
#: erpnext/accounts/doctype/share_transfer/share_transfer.js:18 #: erpnext/accounts/doctype/share_transfer/share_transfer.js:18
msgid "Create Journal Entry" msgid "Create Journal Entry"
@@ -13040,7 +13040,7 @@ msgstr "یک دارایی ترکیبی جدید ایجاد کنید"
#: erpnext/stock/doctype/item/item.js:611 #: erpnext/stock/doctype/item/item.js:611
#: erpnext/stock/doctype/item/item.js:765 #: erpnext/stock/doctype/item/item.js:765
msgid "Create a variant with the template image." msgid "Create a variant with the template image."
msgstr "" msgstr "ایجاد یک گونه با تصویر قالب."
#: erpnext/stock/stock_ledger.py:1831 #: erpnext/stock/stock_ledger.py:1831
msgid "Create an incoming stock transaction for the Item." msgid "Create an incoming stock transaction for the Item."
@@ -13054,7 +13054,7 @@ msgstr "ایجاد پیش فاکتور های مشتری"
#. Settings' #. Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json #: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
msgid "Create in Draft Status" msgid "Create in Draft Status"
msgstr "" msgstr "ایجاد در وضعیت پیش نویس"
#. Description of the 'Create Missing Party' (Check) field in DocType 'Opening #. Description of the 'Create Missing Party' (Check) field in DocType 'Opening
#. Invoice Creation Tool' #. Invoice Creation Tool'
@@ -13092,7 +13092,7 @@ msgstr "ایجاد ابعاد..."
#: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js:92 #: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js:92
msgid "Creating Journal Entries..." msgid "Creating Journal Entries..."
msgstr "" msgstr "در حال ایجاد ثبت دفتر روزنامه..."
#: erpnext/stock/doctype/packing_slip/packing_slip.js:42 #: erpnext/stock/doctype/packing_slip/packing_slip.js:42
msgid "Creating Packing Slip ..." msgid "Creating Packing Slip ..."
@@ -17421,7 +17421,7 @@ msgstr "آیا واقعاً می خواهید این دارایی از بین ر
#: erpnext/stock/doctype/stock_settings/stock_settings.js:44 #: erpnext/stock/doctype/stock_settings/stock_settings.js:44
msgid "Do you still want to enable negative inventory?" msgid "Do you still want to enable negative inventory?"
msgstr "" msgstr "آیا همچنان می خواهید موجودی منفی را فعال کنید؟"
#: erpnext/public/js/controllers/transaction.js:1040 #: erpnext/public/js/controllers/transaction.js:1040
msgid "Do you want to clear the selected {0}?" msgid "Do you want to clear the selected {0}?"
@@ -17625,7 +17625,7 @@ msgstr "دانلود PDF"
#: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:149 #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.js:149
msgid "Download PDF for Supplier" msgid "Download PDF for Supplier"
msgstr "" msgstr "دانلود PDF برای تامین کننده"
#. Label of the download_template (Button) field in DocType 'Bank Statement #. Label of the download_template (Button) field in DocType 'Bank Statement
#. Import' #. Import'
@@ -19534,11 +19534,11 @@ msgstr "حساب هزینه برای مورد {0} اجباری است"
#: erpnext/assets/doctype/asset_repair/asset_repair.py:98 #: erpnext/assets/doctype/asset_repair/asset_repair.py:98
msgid "Expense account not present in Purchase Invoice {0}" msgid "Expense account not present in Purchase Invoice {0}"
msgstr "" msgstr "حساب هزینه در فاکتور خرید {0} وجود ندارد"
#: erpnext/assets/doctype/asset_repair/asset_repair.py:83 #: erpnext/assets/doctype/asset_repair/asset_repair.py:83
msgid "Expense item not present in Purchase Invoice" msgid "Expense item not present in Purchase Invoice"
msgstr "" msgstr "آیتم هزینه در فاکتور خرید وجود ندارد"
#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:42 #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:42
#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:61 #: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:61
@@ -20562,7 +20562,7 @@ msgstr "فوت"
#. Name of a UOM #. Name of a UOM
#: erpnext/setup/setup_wizard/data/uom_data.json #: erpnext/setup/setup_wizard/data/uom_data.json
msgid "Foot Of Water" msgid "Foot Of Water"
msgstr "" msgstr "فوت آب"
#. Name of a UOM #. Name of a UOM
#: erpnext/setup/setup_wizard/data/uom_data.json #: erpnext/setup/setup_wizard/data/uom_data.json
@@ -24186,7 +24186,7 @@ msgstr "نوع پرداخت نادرست"
#: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py:93 #: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py:93
msgid "Incorrect Reference Document (Purchase Receipt Item)" msgid "Incorrect Reference Document (Purchase Receipt Item)"
msgstr "" msgstr "سند مرجع نادرست (آیتم رسید خرید)"
#. Name of a report #. Name of a report
#: erpnext/stock/report/incorrect_serial_no_valuation/incorrect_serial_no_valuation.json #: erpnext/stock/report/incorrect_serial_no_valuation/incorrect_serial_no_valuation.json
@@ -24701,7 +24701,7 @@ msgstr ""
#: erpnext/accounts/doctype/payment_request/payment_request.py:121 #: erpnext/accounts/doctype/payment_request/payment_request.py:121
msgid "Invalid Amount" msgid "Invalid Amount"
msgstr "" msgstr "مبلغ نامعتبر"
#: erpnext/controllers/item_variant.py:128 #: erpnext/controllers/item_variant.py:128
msgid "Invalid Attribute" msgid "Invalid Attribute"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: info@erpnext.com\n" "Report-Msgid-Bugs-To: info@erpnext.com\n"
"POT-Creation-Date: 2024-12-01 09:35+0000\n" "POT-Creation-Date: 2024-12-01 09:35+0000\n"
"PO-Revision-Date: 2024-12-02 11:56\n" "PO-Revision-Date: 2024-12-04 14:18\n"
"Last-Translator: info@erpnext.com\n" "Last-Translator: info@erpnext.com\n"
"Language-Team: Swedish\n" "Language-Team: Swedish\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -4162,7 +4162,7 @@ msgstr "Tillåt Retur"
#. DocType 'Stock Settings' #. DocType 'Stock Settings'
#: erpnext/stock/doctype/stock_settings/stock_settings.json #: erpnext/stock/doctype/stock_settings/stock_settings.json
msgid "Allow Internal Transfers at Arm's Length Price" msgid "Allow Internal Transfers at Arm's Length Price"
msgstr "Tillåt Interna Överföringar till Marknad Pris" msgstr "Tillåt Interna Överföringar till Marknadsmässig Pris"
#. Label of the allow_multiple_items (Check) field in DocType 'Buying Settings' #. Label of the allow_multiple_items (Check) field in DocType 'Buying Settings'
#: erpnext/buying/doctype/buying_settings/buying_settings.json #: erpnext/buying/doctype/buying_settings/buying_settings.json
@@ -5495,7 +5495,7 @@ msgstr "Eftersom det finns reserverat lager kan du inte inaktivera {0}."
#: erpnext/manufacturing/doctype/production_plan/production_plan.py:949 #: erpnext/manufacturing/doctype/production_plan/production_plan.py:949
msgid "As there are sufficient Sub Assembly Items, Work Order is not required for Warehouse {0}." msgid "As there are sufficient Sub Assembly Items, Work Order is not required for Warehouse {0}."
msgstr "Eftersom det finns tillräckligt med Undermontering Artiklar erfordras inte Arbetsorder för Lager {0}." msgstr "Eftersom det finns tillräckligt med Underenhet Artiklar erfordras inte Arbetsorder för Lager {0}."
#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1647 #: erpnext/manufacturing/doctype/production_plan/production_plan.py:1647
msgid "As there are sufficient raw materials, Material Request is not required for Warehouse {0}." msgid "As there are sufficient raw materials, Material Request is not required for Warehouse {0}."
@@ -14314,7 +14314,7 @@ msgstr "Kund Lokal Inköp Order Nummer"
#: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.json #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.json
#: erpnext/accounts/workspace/financial_reports/financial_reports.json #: erpnext/accounts/workspace/financial_reports/financial_reports.json
msgid "Customer Ledger Summary" msgid "Customer Ledger Summary"
msgstr "Kund Register Översikt" msgstr "Kund Register"
#. Label of the customer_contact_mobile (Small Text) field in DocType 'Purchase #. Label of the customer_contact_mobile (Small Text) field in DocType 'Purchase
#. Order' #. Order'
@@ -23267,7 +23267,7 @@ msgstr "Om vald delas betalt belopp och fördelas enligt belopp i betalning sche
#. DocType 'Production Plan' #. DocType 'Production Plan'
#: erpnext/manufacturing/doctype/production_plan/production_plan.json #: erpnext/manufacturing/doctype/production_plan/production_plan.json
msgid "If this checkbox is enabled, then the system wont run the MRP for the available sub-assembly items." msgid "If this checkbox is enabled, then the system wont run the MRP for the available sub-assembly items."
msgstr "Om vald kommer systemet inte att köra Material Resurs Planering för tillgängliga undermontering artiklar." msgstr "Om vald kommer systemet inte att köra Material Resurs Planering för tillgängliga underenhet artiklar."
#. Description of the 'Follow Calendar Months' (Check) field in DocType #. Description of the 'Follow Calendar Months' (Check) field in DocType
#. 'Subscription' #. 'Subscription'
@@ -23334,7 +23334,7 @@ msgstr "Om man behöver stämma av specifika transaktioner mot varandra, välj d
#: erpnext/manufacturing/doctype/production_plan/production_plan.py:954 #: erpnext/manufacturing/doctype/production_plan/production_plan.py:954
msgid "If you still want to proceed, please disable 'Skip Available Sub Assembly Items' checkbox." msgid "If you still want to proceed, please disable 'Skip Available Sub Assembly Items' checkbox."
msgstr "Om du fortfarande vill fortsätta, avmarkera \"Hoppa över tillgängliga undermontering artiklar\"." msgstr "Om du fortfarande vill fortsätta, avmarkera \"Hoppa över tillgängliga underenhet artiklar\"."
#: erpnext/manufacturing/doctype/production_plan/production_plan.py:1652 #: erpnext/manufacturing/doctype/production_plan/production_plan.py:1652
msgid "If you still want to proceed, please enable {0}." msgid "If you still want to proceed, please enable {0}."
@@ -23944,7 +23944,7 @@ msgstr "I Lager"
#. (Check) field in DocType 'Manufacturing Settings' #. (Check) field in DocType 'Manufacturing Settings'
#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json #: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
msgid "In the case of 'Use Multi-Level BOM' in a work order, if the user wishes to add sub-assembly costs to Finished Goods items without using a job card as well the scrap items, then this option needs to be enable." msgid "In the case of 'Use Multi-Level BOM' in a work order, if the user wishes to add sub-assembly costs to Finished Goods items without using a job card as well the scrap items, then this option needs to be enable."
msgstr "I fall att 'Använd Flernivå Stycklista' används i arbetsorder, om användare vill lägga till undermontering kostnader till färdiga artiklar utan att använda jobbkort samt rest artiklar, måste detta alternativ vara aktiverad." msgstr "I fall att 'Använd Flernivå Stycklista' används i arbetsorder, om användare vill lägga till underenhet kostnader till färdiga artiklar utan att använda jobbkort samt rest artiklar, måste detta alternativ vara aktiverad."
#: erpnext/accounts/doctype/loyalty_program/loyalty_program.js:12 #: erpnext/accounts/doctype/loyalty_program/loyalty_program.js:12
msgid "In the case of multi-tier program, Customers will be auto assigned to the concerned tier as per their spent" msgid "In the case of multi-tier program, Customers will be auto assigned to the concerned tier as per their spent"
@@ -24127,7 +24127,7 @@ msgstr "Inkludera Säkerhet Lager i Begärd Kvantitet Beräkning"
#: erpnext/manufacturing/report/production_planning_report/production_planning_report.js:87 #: erpnext/manufacturing/report/production_planning_report/production_planning_report.js:87
msgid "Include Sub-assembly Raw Materials" msgid "Include Sub-assembly Raw Materials"
msgstr "Inkludera Undermontering Råmaterial" msgstr "Inkludera Underenhet Råmaterial"
#. Label of the include_subcontracted_items (Check) field in DocType #. Label of the include_subcontracted_items (Check) field in DocType
#. 'Production Plan' #. 'Production Plan'
@@ -24165,7 +24165,7 @@ msgstr "Inkluderad i Brutto Resultat"
#. Entry' #. Entry'
#: erpnext/stock/doctype/stock_entry/stock_entry.json #: erpnext/stock/doctype/stock_entry/stock_entry.json
msgid "Including items for sub assemblies" msgid "Including items for sub assemblies"
msgstr "Inklusive Artiklar för Undermontering" msgstr "Inklusive artiklar för underenhet"
#. Option for the 'Root Type' (Select) field in DocType 'Account' #. Option for the 'Root Type' (Select) field in DocType 'Account'
#. Option for the 'Root Type' (Select) field in DocType 'Ledger Merge' #. Option for the 'Root Type' (Select) field in DocType 'Ledger Merge'
@@ -35916,7 +35916,7 @@ msgstr "Kontinuerlig Lager Hantering erfordras för bolag {0} om man ska kunna s
#. Label of the personal_details (Tab Break) field in DocType 'Employee' #. Label of the personal_details (Tab Break) field in DocType 'Employee'
#: erpnext/setup/doctype/employee/employee.json #: erpnext/setup/doctype/employee/employee.json
msgid "Personal" msgid "Personal"
msgstr "Personal" msgstr "Personligt"
#. Option for the 'Preferred Contact Email' (Select) field in DocType #. Option for the 'Preferred Contact Email' (Select) field in DocType
#. 'Employee' #. 'Employee'
@@ -44461,7 +44461,7 @@ msgstr "Rad # {0}: Välj Stycklista Nummer för Montering Artiklar"
#: erpnext/manufacturing/doctype/production_plan/production_plan.py:932 #: erpnext/manufacturing/doctype/production_plan/production_plan.py:932
msgid "Row #{0}: Please select the Sub Assembly Warehouse" msgid "Row #{0}: Please select the Sub Assembly Warehouse"
msgstr "Rad # {0}: Välj Undermontering Lager" msgstr "Rad #{0}: Välj Underenhet Lager"
#: erpnext/stock/doctype/item/item.py:500 #: erpnext/stock/doctype/item/item.py:500
msgid "Row #{0}: Please set reorder quantity" msgid "Row #{0}: Please set reorder quantity"
@@ -50390,7 +50390,7 @@ msgstr "Underenhet Artikel Kod"
#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:403 #: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:403
msgid "Sub Assembly Item is mandatory" msgid "Sub Assembly Item is mandatory"
msgstr "Undermontering artikel erfordras" msgstr "Underenhet artikel erfordras"
#. Label of the section_break_24 (Section Break) field in DocType 'Production #. Label of the section_break_24 (Section Break) field in DocType 'Production
#. Plan' #. Plan'
@@ -54403,7 +54403,7 @@ msgstr "Att använda annan finans register, inaktivera \"Inkludera Standard Fina
#: erpnext/selling/page/point_of_sale/pos_controller.js:192 #: erpnext/selling/page/point_of_sale/pos_controller.js:192
msgid "Toggle Recent Orders" msgid "Toggle Recent Orders"
msgstr "Växla Senaste Ordrar" msgstr "Ändra Senaste Ordrar"
#. Label of the token_endpoint (Data) field in DocType 'QuickBooks Migrator' #. Label of the token_endpoint (Data) field in DocType 'QuickBooks Migrator'
#: erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.json #: erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.json

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: info@erpnext.com\n" "Report-Msgid-Bugs-To: info@erpnext.com\n"
"POT-Creation-Date: 2024-12-01 09:35+0000\n" "POT-Creation-Date: 2024-12-01 09:35+0000\n"
"PO-Revision-Date: 2024-12-01 11:47\n" "PO-Revision-Date: 2024-12-04 14:18\n"
"Last-Translator: info@erpnext.com\n" "Last-Translator: info@erpnext.com\n"
"Language-Team: Turkish\n" "Language-Team: Turkish\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -833,7 +833,7 @@ msgid "<span class=\"h4\"><b>Your Shortcuts\n"
"\t\t\n" "\t\t\n"
"\t\t\t\n" "\t\t\t\n"
"\t\t</b></span>" "\t\t</b></span>"
msgstr "<span class=\"h4\"><b>Kısayollarınız\n" msgstr "<span class=\"h4\"><b>Kısayollar\n"
"\t\t\t\n" "\t\t\t\n"
"\t\t\n" "\t\t\n"
"\t\t\t\n" "\t\t\t\n"
@@ -858,7 +858,7 @@ msgstr "<span class=\"h4\"><b>Kısayollarınız\n"
#: erpnext/setup/workspace/home/home.json #: erpnext/setup/workspace/home/home.json
#: erpnext/support/workspace/support/support.json #: erpnext/support/workspace/support/support.json
msgid "<span class=\"h4\"><b>Your Shortcuts</b></span>" msgid "<span class=\"h4\"><b>Your Shortcuts</b></span>"
msgstr "<span class=\"h4\"><b>Kısayollarınız</b></span>" msgstr "<span class=\"h4\"><b>Kısayollar</b></span>"
#: erpnext/accounts/doctype/payment_request/payment_request.py:998 #: erpnext/accounts/doctype/payment_request/payment_request.py:998
msgid "<strong>Grand Total:</strong> {0}" msgid "<strong>Grand Total:</strong> {0}"
@@ -3903,7 +3903,7 @@ msgstr "Tüm Müşteri Adayları (Açık)"
#: erpnext/accounts/report/general_ledger/general_ledger.html:68 #: erpnext/accounts/report/general_ledger/general_ledger.html:68
msgid "All Parties " msgid "All Parties "
msgstr "" msgstr "Tüm Partiler "
#. Option for the 'Send To' (Select) field in DocType 'SMS Center' #. Option for the 'Send To' (Select) field in DocType 'SMS Center'
#: erpnext/selling/doctype/sms_center/sms_center.json #: erpnext/selling/doctype/sms_center/sms_center.json
@@ -17641,7 +17641,7 @@ msgstr "Etki Alanı Ayarları"
#. Invoice' #. Invoice'
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json
msgid "Don't Create Loyalty Points" msgid "Don't Create Loyalty Points"
msgstr "" msgstr "Sadakat Puanları Oluşturma"
#. Label of the dont_reserve_sales_order_qty_on_sales_return (Check) field in #. Label of the dont_reserve_sales_order_qty_on_sales_return (Check) field in
#. DocType 'Selling Settings' #. DocType 'Selling Settings'
@@ -34467,7 +34467,7 @@ msgstr "Ana Depo"
#: erpnext/edi/doctype/code_list/code_list_import.py:39 #: erpnext/edi/doctype/code_list/code_list_import.py:39
msgid "Parsing Error" msgid "Parsing Error"
msgstr "" msgstr "Birleştirme Hatası"
#. Option for the 'Status' (Select) field in DocType 'Subcontracting Order' #. Option for the 'Status' (Select) field in DocType 'Subcontracting Order'
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.json #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.json
@@ -39432,7 +39432,7 @@ msgstr "Yayınlanma Tarihi"
#. Label of the publisher (Data) field in DocType 'Code List' #. Label of the publisher (Data) field in DocType 'Code List'
#: erpnext/edi/doctype/code_list/code_list.json #: erpnext/edi/doctype/code_list/code_list.json
msgid "Publisher" msgid "Publisher"
msgstr "" msgstr "Yayınlayan"
#. Label of the publisher_id (Data) field in DocType 'Code List' #. Label of the publisher_id (Data) field in DocType 'Code List'
#: erpnext/edi/doctype/code_list/code_list.json #: erpnext/edi/doctype/code_list/code_list.json
@@ -40175,7 +40175,7 @@ msgstr "Miktar "
#: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/doctype/sales_order_item/sales_order_item.json
#: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
msgid "Qty (Company)" msgid "Qty (Company)"
msgstr "" msgstr "Miktar (Şirket)"
#. Label of the actual_qty (Float) field in DocType 'Sales Invoice Item' #. Label of the actual_qty (Float) field in DocType 'Sales Invoice Item'
#. Label of the actual_qty (Float) field in DocType 'Quotation Item' #. Label of the actual_qty (Float) field in DocType 'Quotation Item'
@@ -40186,7 +40186,7 @@ msgstr ""
#: erpnext/selling/doctype/sales_order_item/sales_order_item.json #: erpnext/selling/doctype/sales_order_item/sales_order_item.json
#: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
msgid "Qty (Warehouse)" msgid "Qty (Warehouse)"
msgstr "" msgstr "Miktar (Depo)"
#. Label of the qty_after_transaction (Float) field in DocType 'Stock Ledger #. Label of the qty_after_transaction (Float) field in DocType 'Stock Ledger
#. Entry' #. Entry'

View File

@@ -264,6 +264,24 @@ class BOM(WebsiteGenerator):
self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate=False, save=False) self.update_cost(update_parent=False, from_child_bom=True, update_hour_rate=False, save=False)
self.set_process_loss_qty() self.set_process_loss_qty()
self.validate_scrap_items() self.validate_scrap_items()
self.set_default_uom()
def set_default_uom(self):
if not self.get("items"):
return
item_wise_uom = frappe._dict(
frappe.get_all(
"Item",
filters={"name": ("in", [item.item_code for item in self.items])},
fields=["name", "stock_uom"],
as_list=1,
)
)
for row in self.get("items"):
if row.stock_uom != item_wise_uom.get(row.item_code):
row.stock_uom = item_wise_uom.get(row.item_code)
def get_context(self, context): def get_context(self, context):
context.parents = [{"name": "boms", "title": _("All BOMs")}] context.parents = [{"name": "boms", "title": _("All BOMs")}]

View File

@@ -763,6 +763,26 @@ class TestBOM(IntegrationTestCase):
self.assertTrue("_Test RM Item 2 Fixed Asset Item" not in items) self.assertTrue("_Test RM Item 2 Fixed Asset Item" not in items)
self.assertTrue("_Test RM Item 3 Manufacture Item" in items) self.assertTrue("_Test RM Item 3 Manufacture Item" in items)
def test_bom_raw_materials_stock_uom(self):
rm_item = make_item(
properties={"is_stock_item": 1, "valuation_rate": 1000.0, "stock_uom": "Nos"}
).name
fg_item = make_item(properties={"is_stock_item": 1}).name
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
bom = make_bom(item=fg_item, raw_materials=[rm_item], do_not_submit=True)
for row in bom.items:
self.assertEqual(row.stock_uom, "Nos")
frappe.db.set_value("Item", rm_item, "stock_uom", "Kg")
bom.items[0].qty = 2
bom.save()
for row in bom.items:
self.assertEqual(row.stock_uom, "Kg")
def get_default_bom(item_code="_Test FG Item 2"): def get_default_bom(item_code="_Test FG Item 2"):
return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1}) return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})

View File

@@ -243,7 +243,7 @@
"depends_on": "eval:!doc.__islocal", "depends_on": "eval:!doc.__islocal",
"fieldname": "download_materials_required", "fieldname": "download_materials_required",
"fieldtype": "Button", "fieldtype": "Button",
"label": "Download Materials Request Plan" "label": "Download Required Materials"
}, },
{ {
"fieldname": "get_items_for_mr", "fieldname": "get_items_for_mr",
@@ -398,7 +398,7 @@
"collapsible": 1, "collapsible": 1,
"fieldname": "download_materials_request_plan_section_section", "fieldname": "download_materials_request_plan_section_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Download Materials Request Plan Section" "label": "Preview Required Materials"
}, },
{ {
"default": "0", "default": "0",
@@ -439,7 +439,7 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2024-03-27 13:10:19.928403", "modified": "2024-12-04 11:55:03.108971",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Production Plan", "name": "Production Plan",

View File

@@ -44,9 +44,7 @@ class ProductionPlan(Document):
from erpnext.manufacturing.doctype.material_request_plan_item.material_request_plan_item import ( from erpnext.manufacturing.doctype.material_request_plan_item.material_request_plan_item import (
MaterialRequestPlanItem, MaterialRequestPlanItem,
) )
from erpnext.manufacturing.doctype.production_plan_item.production_plan_item import ( from erpnext.manufacturing.doctype.production_plan_item.production_plan_item import ProductionPlanItem
ProductionPlanItem,
)
from erpnext.manufacturing.doctype.production_plan_item_reference.production_plan_item_reference import ( from erpnext.manufacturing.doctype.production_plan_item_reference.production_plan_item_reference import (
ProductionPlanItemReference, ProductionPlanItemReference,
) )
@@ -1085,24 +1083,33 @@ def download_raw_materials(doc, warehouses=None):
frappe.flags.show_qty_in_stock_uom = 1 frappe.flags.show_qty_in_stock_uom = 1
items = get_items_for_material_requests(doc, warehouses=warehouses, get_parent_warehouse_data=True) items = get_items_for_material_requests(doc, warehouses=warehouses, get_parent_warehouse_data=True)
duplicate_item_wh_list = frappe._dict()
for d in items: for d in items:
item_list.append( key = (d.get("item_code"), d.get("warehouse"))
[ if key in duplicate_item_wh_list:
d.get("item_code"), rm_data = duplicate_item_wh_list[key]
d.get("item_name"), rm_data[12] += d.get("quantity")
d.get("description"), continue
d.get("stock_uom"),
d.get("warehouse"), rm_data = [
d.get("required_bom_qty"), d.get("item_code"),
d.get("projected_qty"), d.get("item_name"),
d.get("actual_qty"), d.get("description"),
d.get("ordered_qty"), d.get("stock_uom"),
d.get("planned_qty"), d.get("warehouse"),
d.get("reserved_qty_for_production"), d.get("required_bom_qty"),
d.get("safety_stock"), d.get("projected_qty"),
d.get("quantity"), d.get("actual_qty"),
] d.get("ordered_qty"),
) d.get("planned_qty"),
d.get("reserved_qty_for_production"),
d.get("safety_stock"),
d.get("quantity"),
]
duplicate_item_wh_list[key] = rm_data
item_list.append(rm_data)
if not doc.get("for_warehouse"): if not doc.get("for_warehouse"):
row = {"item_code": d.get("item_code")} row = {"item_code": d.get("item_code")}

View File

@@ -58,10 +58,10 @@ frappe.ui.form.on("Timesheet", {
} }
if (frm.doc.docstatus < 1) { if (frm.doc.docstatus < 1) {
let button = "Start Timer"; let button = __("Start Timer");
$.each(frm.doc.time_logs || [], function (i, row) { $.each(frm.doc.time_logs || [], function (i, row) {
if (row.from_time <= frappe.datetime.now_datetime() && !row.completed) { if (row.from_time <= frappe.datetime.now_datetime() && !row.completed) {
button = "Resume Timer"; button = __("Resume Timer");
} }
}); });

View File

@@ -448,6 +448,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
get_current_tax_amount(item, tax, item_tax_map) { get_current_tax_amount(item, tax, item_tax_map) {
var tax_rate = this._get_tax_rate(tax, item_tax_map); var tax_rate = this._get_tax_rate(tax, item_tax_map);
var current_tax_amount = 0.0; var current_tax_amount = 0.0;
var current_net_amount = 0.0;
// To set row_id by default as previous row. // To set row_id by default as previous row.
if(["On Previous Row Amount", "On Previous Row Total"].includes(tax.charge_type)) { if(["On Previous Row Amount", "On Previous Row Total"].includes(tax.charge_type)) {
@@ -460,21 +461,27 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
} }
} }
if(tax.charge_type == "Actual") { if(tax.charge_type == "Actual") {
current_net_amount = item.net_amount
// distribute the tax amount proportionally to each item row // distribute the tax amount proportionally to each item row
var actual = flt(tax.tax_amount, precision("tax_amount", tax)); var actual = flt(tax.tax_amount, precision("tax_amount", tax));
current_tax_amount = this.frm.doc.net_total ? current_tax_amount = this.frm.doc.net_total ?
((item.net_amount / this.frm.doc.net_total) * actual) : 0.0; ((item.net_amount / this.frm.doc.net_total) * actual) : 0.0;
} else if(tax.charge_type == "On Net Total") { } else if(tax.charge_type == "On Net Total") {
if (tax.account_head in item_tax_map) {
current_net_amount = item.net_amount
};
current_tax_amount = (tax_rate / 100.0) * item.net_amount; current_tax_amount = (tax_rate / 100.0) * item.net_amount;
} else if(tax.charge_type == "On Previous Row Amount") { } else if(tax.charge_type == "On Previous Row Amount") {
current_net_amount = this.frm.doc["taxes"][cint(tax.row_id) - 1].tax_amount_for_current_item
current_tax_amount = (tax_rate / 100.0) * current_tax_amount = (tax_rate / 100.0) *
this.frm.doc["taxes"][cint(tax.row_id) - 1].tax_amount_for_current_item; this.frm.doc["taxes"][cint(tax.row_id) - 1].tax_amount_for_current_item;
} else if(tax.charge_type == "On Previous Row Total") { } else if(tax.charge_type == "On Previous Row Total") {
current_net_amount = this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item
current_tax_amount = (tax_rate / 100.0) * current_tax_amount = (tax_rate / 100.0) *
this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item; this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item;
} else if (tax.charge_type == "On Item Quantity") { } else if (tax.charge_type == "On Item Quantity") {
// don't sum current net amount due to the field being a currency field
current_tax_amount = tax_rate * item.qty; current_tax_amount = tax_rate * item.qty;
} }
@@ -504,17 +511,16 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
item_wise_tax_amount += flt(tax_detail[key].tax_amount, precision("tax_amount", tax)); item_wise_tax_amount += flt(tax_detail[key].tax_amount, precision("tax_amount", tax));
item_wise_net_amount += flt(tax_detail[key].net_amount, precision("net_amount", tax)); item_wise_net_amount += flt(tax_detail[key].net_amount, precision("net_amount", tax));
} }
} else { } else if (tax_detail && tax_detail[key]) {
if (tax_detail && tax_detail[key]) item_wise_tax_amount += tax_detail[key].tax_amount;
item_wise_tax_amount += tax_detail[key].tax_amount; item_wise_net_amount += tax_detail[key].net_amount;
item_wise_net_amount += tax_detail[key].net_amount;
} }
tax_detail[key] = { tax_detail[key] = {
tax_rate: tax_rate, tax_rate: tax_rate,
tax_amount: flt(item_wise_tax_amount, precision("base_tax_amount", tax)), tax_amount: flt(item_wise_tax_amount, precision("base_tax_amount", tax)),
net_amount: flt(item_wise_net_amount, precision("base_net_amount", tax)), net_amount: flt(item_wise_net_amount, precision("base_net_amount", tax)),
}; };
} }
round_off_totals(tax) { round_off_totals(tax) {

View File

@@ -146,7 +146,7 @@ frappe.ui.form.on("Sales Order", {
target: frm, target: frm,
setters: [ setters: [
{ {
label: "Supplier", label: __("Supplier"),
fieldname: "supplier", fieldname: "supplier",
fieldtype: "Link", fieldtype: "Link",
options: "Supplier", options: "Supplier",
@@ -783,7 +783,7 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex
target: me.frm, target: me.frm,
setters: [ setters: [
{ {
label: "Customer", label: __("Customer"),
fieldname: "party_name", fieldname: "party_name",
fieldtype: "Link", fieldtype: "Link",
options: "Customer", options: "Customer",
@@ -830,7 +830,7 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex
} else { } else {
const fields = [ const fields = [
{ {
label: "Items", label: __("Items"),
fieldtype: "Table", fieldtype: "Table",
fieldname: "items", fieldname: "items",
description: __("Select BOM and Qty for Production"), description: __("Select BOM and Qty for Production"),
@@ -1191,7 +1191,7 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex
{ {
fieldname: "items_for_po", fieldname: "items_for_po",
fieldtype: "Table", fieldtype: "Table",
label: "Select Items", label: __("Select Items"),
fields: [ fields: [
{ {
fieldtype: "Data", fieldtype: "Data",

View File

@@ -30,7 +30,7 @@ erpnext.PointOfSale.Controller = class {
fieldname: "mode_of_payment", fieldname: "mode_of_payment",
fieldtype: "Link", fieldtype: "Link",
in_list_view: 1, in_list_view: 1,
label: "Mode of Payment", label: __("Mode of Payment"),
options: "Mode of Payment", options: "Mode of Payment",
reqd: 1, reqd: 1,
}, },
@@ -38,7 +38,7 @@ erpnext.PointOfSale.Controller = class {
fieldname: "opening_amount", fieldname: "opening_amount",
fieldtype: "Currency", fieldtype: "Currency",
in_list_view: 1, in_list_view: 1,
label: "Opening Amount", label: __("Opening Amount"),
options: "company:company_currency", options: "company:company_currency",
change: function () { change: function () {
dialog.fields_dict.balance_details.df.data.some((d) => { dialog.fields_dict.balance_details.df.data.some((d) => {
@@ -87,7 +87,7 @@ erpnext.PointOfSale.Controller = class {
{ {
fieldname: "balance_details", fieldname: "balance_details",
fieldtype: "Table", fieldtype: "Table",
label: "Opening Balance Details", label: __("Opening Balance Details"),
cannot_add_rows: false, cannot_add_rows: false,
in_place_edit: true, in_place_edit: true,
reqd: 1, reqd: 1,

View File

@@ -966,13 +966,15 @@ erpnext.PointOfSale.ItemCart = class {
if (!res.length) { if (!res.length) {
transaction_container.html( transaction_container.html(
`<div class="no-transactions-placeholder">No recent transactions found</div>` `<div class="no-transactions-placeholder">${__("No recent transactions found")}</div>`
); );
return; return;
} }
const elapsed_time = moment(res[0].posting_date + " " + res[0].posting_time).fromNow(); const elapsed_time = moment(res[0].posting_date + " " + res[0].posting_time).fromNow();
this.$customer_section.find(".customer-desc").html(`Last transacted ${elapsed_time}`); this.$customer_section
.find(".customer-desc")
.html(`${__("Last transacted")} ${__(elapsed_time)}`);
res.forEach((invoice) => { res.forEach((invoice) => {
const posting_datetime = moment(invoice.posting_date + " " + invoice.posting_time).format( const posting_datetime = moment(invoice.posting_date + " " + invoice.posting_time).format(
@@ -997,7 +999,7 @@ erpnext.PointOfSale.ItemCart = class {
</div> </div>
<div class="invoice-status"> <div class="invoice-status">
<span class="indicator-pill whitespace-nowrap ${indicator_color[invoice.status]}"> <span class="indicator-pill whitespace-nowrap ${indicator_color[invoice.status]}">
<span>${invoice.status}</span> <span>${__(invoice.status)}</span>
</span> </span>
</div> </div>
</div> </div>

View File

@@ -46,7 +46,7 @@ erpnext.PointOfSale.PastOrderSummary = class {
init_email_print_dialog() { init_email_print_dialog() {
const email_dialog = new frappe.ui.Dialog({ const email_dialog = new frappe.ui.Dialog({
title: "Email Receipt", title: __("Email Receipt"),
fields: [ fields: [
{ fieldname: "email_id", fieldtype: "Data", options: "Email", label: "Email ID", reqd: 1 }, { fieldname: "email_id", fieldtype: "Data", options: "Email", label: "Email ID", reqd: 1 },
{ fieldname: "content", fieldtype: "Small Text", label: "Message (if any)" }, { fieldname: "content", fieldtype: "Small Text", label: "Message (if any)" },
@@ -59,7 +59,7 @@ erpnext.PointOfSale.PastOrderSummary = class {
this.email_dialog = email_dialog; this.email_dialog = email_dialog;
const print_dialog = new frappe.ui.Dialog({ const print_dialog = new frappe.ui.Dialog({
title: "Print Receipt", title: __("Print Receipt"),
fields: [{ fieldname: "print", fieldtype: "Data", label: "Print Preview" }], fields: [{ fieldname: "print", fieldtype: "Data", label: "Print Preview" }],
primary_action: () => { primary_action: () => {
this.print_receipt(); this.print_receipt();
@@ -112,7 +112,7 @@ erpnext.PointOfSale.PastOrderSummary = class {
get_discount_html(doc) { get_discount_html(doc) {
if (doc.discount_amount) { if (doc.discount_amount) {
return `<div class="summary-row-wrapper"> return `<div class="summary-row-wrapper">
<div>Discount (${doc.additional_discount_percentage} %)</div> <div>${__("Discount")} (${doc.additional_discount_percentage} %)</div>
<div>${format_currency(doc.discount_amount, doc.currency)}</div> <div>${format_currency(doc.discount_amount, doc.currency)}</div>
</div>`; </div>`;
} else { } else {

View File

@@ -589,7 +589,7 @@ erpnext.PointOfSale.Payment = class {
const remaining = grand_total - doc.paid_amount; const remaining = grand_total - doc.paid_amount;
const change = doc.change_amount || remaining <= 0 ? -1 * remaining : undefined; const change = doc.change_amount || remaining <= 0 ? -1 * remaining : undefined;
const currency = doc.currency; const currency = doc.currency;
const label = change ? __("Change") : __("To Be Paid"); const label = __("Change Amount");
this.$totals.html( this.$totals.html(
`<div class="col"> `<div class="col">

View File

@@ -214,13 +214,10 @@ class InventoryDimension(Document):
dimension_fields = [] dimension_fields = []
if self.apply_to_all_doctypes: if self.apply_to_all_doctypes:
for doctype in get_inventory_documents(): for doctype in get_inventory_documents():
if field_exists(doctype[0], self.source_fieldname):
continue
dimension_fields = self.get_dimension_fields(doctype[0]) dimension_fields = self.get_dimension_fields(doctype[0])
self.add_transfer_field(doctype[0], dimension_fields) self.add_transfer_field(doctype[0], dimension_fields)
custom_fields.setdefault(doctype[0], dimension_fields) custom_fields.setdefault(doctype[0], dimension_fields)
elif not field_exists(self.document_type, self.source_fieldname): else:
dimension_fields = self.get_dimension_fields() dimension_fields = self.get_dimension_fields()
self.add_transfer_field(self.document_type, dimension_fields) self.add_transfer_field(self.document_type, dimension_fields)
@@ -239,8 +236,17 @@ class InventoryDimension(Document):
dimension_field["fieldname"] = self.target_fieldname dimension_field["fieldname"] = self.target_fieldname
custom_fields["Stock Ledger Entry"] = dimension_field custom_fields["Stock Ledger Entry"] = dimension_field
filter_custom_fields = {}
if custom_fields: if custom_fields:
create_custom_fields(custom_fields) for doctype, fields in custom_fields.items():
if isinstance(fields, dict):
fields = [fields]
for field in fields:
if not field_exists(doctype, field["fieldname"]):
filter_custom_fields.setdefault(doctype, []).append(field)
create_custom_fields(filter_custom_fields)
def add_transfer_field(self, doctype, dimension_fields): def add_transfer_field(self, doctype, dimension_fields):
if doctype not in [ if doctype not in [

View File

@@ -1663,6 +1663,46 @@ class TestStockEntry(IntegrationTestCase):
mr.cancel() mr.cancel()
mr.delete() mr.delete()
def test_auto_reorder_level_with_lead_time_days(self):
from erpnext.stock.reorder_item import reorder_item
item_doc = make_item(
"Test Auto Reorder Item - 002",
properties={"stock_uom": "Kg", "purchase_uom": "Nos", "is_stock_item": 1, "lead_time_days": 2},
uoms=[{"uom": "Nos", "conversion_factor": 5}],
)
if not frappe.db.exists("Item Reorder", {"parent": item_doc.name}):
item_doc.append(
"reorder_levels",
{
"warehouse_reorder_level": 0,
"warehouse_reorder_qty": 10,
"warehouse": "_Test Warehouse - _TC",
"material_request_type": "Purchase",
},
)
item_doc.save(ignore_permissions=True)
frappe.db.set_single_value("Stock Settings", "auto_indent", 1)
mr_list = reorder_item()
frappe.db.set_single_value("Stock Settings", "auto_indent", 0)
mrs = frappe.get_all(
"Material Request Item",
fields=["schedule_date"],
filters={"item_code": item_doc.name, "uom": "Nos"},
)
for mri in mrs:
self.assertEqual(getdate(mri.schedule_date), getdate(add_days(today(), 2)))
for mr in mr_list:
mr.cancel()
mr.delete()
def test_use_serial_and_batch_fields(self): def test_use_serial_and_batch_fields(self):
item = make_item( item = make_item(
"Test Use Serial and Batch Item SN Item", "Test Use Serial and Batch Item SN Item",

View File

@@ -690,8 +690,8 @@ def is_within_valid_range(ctx: ItemDetailsCtx, tax) -> bool:
def get_item_tax_map(*, doc: str | dict | Document, tax_template: str | None = None, as_json=True): def get_item_tax_map(*, doc: str | dict | Document, tax_template: str | None = None, as_json=True):
doc = parse_json(doc) doc = parse_json(doc)
item_tax_map = {} item_tax_map = {}
for t in (t for t in (doc.get("taxes") or []) if not t.set_by_item_tax_template): for t in (t for t in (doc.get("taxes") or []) if not t.get("set_by_item_tax_template")):
item_tax_map[t.account_head] = t.rate item_tax_map[t.get("account_head")] = t.get("rate")
if tax_template: if tax_template:
template = frappe.get_cached_doc("Item Tax Template", tax_template) template = frappe.get_cached_doc("Item Tax Template", tax_template)

View File

@@ -98,6 +98,7 @@ def _reorder_item():
"description": d.description, "description": d.description,
"stock_uom": d.stock_uom, "stock_uom": d.stock_uom,
"purchase_uom": d.purchase_uom, "purchase_uom": d.purchase_uom,
"lead_time_days": d.lead_time_days,
} }
), ),
) )
@@ -129,6 +130,7 @@ def get_items_for_reorder() -> dict[str, list]:
item_table.brand, item_table.brand,
item_table.variant_of, item_table.variant_of,
item_table.has_variants, item_table.has_variants,
item_table.lead_time_days,
) )
.where( .where(
(item_table.disabled == 0) (item_table.disabled == 0)