Compare commits

...

73 Commits

Author SHA1 Message Date
Frappe PR Bot
0653f6854b chore(release): Bumped to Version 14.63.2
## [14.63.2](https://github.com/frappe/erpnext/compare/v14.63.1...v14.63.2) (2024-02-22)

### Bug Fixes

* Webpages not working without login ([a40e410](a40e410519))
2024-02-22 11:58:43 +00:00
rohitwaghchaure
ee125d5dd8 Merge pull request #40045 from frappe/mergify/bp/version-14/pr-40041
fix: Webpages not working without login (backport #40041)
2024-02-22 17:27:27 +05:30
Rohit Waghchaure
a40e410519 fix: Webpages not working without login
(cherry picked from commit d6fad08d20)
2024-02-22 11:22:20 +00:00
Frappe PR Bot
315d4dec90 chore(release): Bumped to Version 14.63.1
## [14.63.1](https://github.com/frappe/erpnext/compare/v14.63.0...v14.63.1) (2024-02-22)

### Bug Fixes

* negative stock error while making stock reconciliation (backport [#40016](https://github.com/frappe/erpnext/issues/40016)) ([#40025](https://github.com/frappe/erpnext/issues/40025)) ([7355fce](7355fce75e))
2024-02-22 08:18:35 +00:00
rohitwaghchaure
c826b5ce6c Merge pull request #40034 from frappe/mergify/bp/version-14/pr-40025
fix: negative stock error while making stock reconciliation (backport #40016) (backport #40025)
2024-02-22 13:46:44 +05:30
mergify[bot]
7355fce75e fix: negative stock error while making stock reconciliation (backport #40016) (#40025)
* fix: negative stock error while making stock reconciliation (#40016)

fix: negative stock error while making stock reco
(cherry picked from commit da184d709b)

# Conflicts:
#	erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py

* chore: fix conflicts

* chore: fix linter issue

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 865cba406f)
2024-02-22 07:49:51 +00:00
Frappe PR Bot
8ab75560d5 chore(release): Bumped to Version 14.63.0
# [14.63.0](https://github.com/frappe/erpnext/compare/v14.62.4...v14.63.0) (2024-02-21)

### Bug Fixes

* 'NoneType' object is not iterable (backport [#39977](https://github.com/frappe/erpnext/issues/39977)) ([#39980](https://github.com/frappe/erpnext/issues/39980)) ([8e71665](8e71665e4f))
* Adjust amount in last row due to rounding ([963ddac](963ddac528))
* **Bank Transaction:** precision for `(un)allocated_amount` ([cea0e1f](cea0e1fb91)), closes [#39926](https://github.com/frappe/erpnext/issues/39926)
* fetch company terms ([83bf286](83bf28616e))
* group node in warehouse filter in Item-wise Sales Register ([4921b03](4921b038bd))
* **Issue:** create communication ([8deaba8](8deaba8def))
* linter issue ([a4fbea3](a4fbea3722))
* linter issue ([abceb1b](abceb1b611))
* linter issues ([e99485b](e99485bfa7))
* no need call for company method in sales invoice js ([45a0494](45a0494318))
* On cancelation of capitalization, reverse depreciation entry only if journal entry exists ([5b9905f](5b9905f27a))
* party item code in Blanket Order ([ee9a51f](ee9a51f93f))
* reconciliation issue due to notation difference ([dcf19c3](dcf19c3ed9))
* show active bom in the dropdown while making stock entry and MR (backport [#39974](https://github.com/frappe/erpnext/issues/39974)) ([#39975](https://github.com/frappe/erpnext/issues/39975)) ([385b08d](385b08dc50))
* typeerror 'Item Group' filter on Purchase Register ([b1a4249](b1a4249041))
* update_dimension is required and not need party account method ([5eaa11b](5eaa11b9e8))
* webpages are not showing ([#39988](https://github.com/frappe/erpnext/issues/39988)) ([64099b0](64099b0bf7))

### Features

* New financial views - Growth and margin views for P&L and balance sheet ([d913ec5](d913ec52db))
2024-02-21 05:30:04 +00:00
rohitwaghchaure
7561de1f4e Merge pull request #39978 from frappe/version-14-hotfix
chore: release v14
2024-02-21 10:58:47 +05:30
rohitwaghchaure
64099b0bf7 fix: webpages are not showing (#39988) 2024-02-21 09:26:58 +05:30
Nabin Hait
46762ead05 Merge pull request #39982 from nabinhait/asset-capitalization-cancel
fix: On cancelation of capitalization, reverse depreciation entry only if journal entry exists
2024-02-20 18:30:14 +05:30
Nabin Hait
5b9905f27a fix: On cancelation of capitalization, reverse depreciation entry only if journal entry exists 2024-02-20 17:54:58 +05:30
mergify[bot]
8e71665e4f fix: 'NoneType' object is not iterable (backport #39977) (#39980)
fix: 'NoneType' object is not iterable (#39977)

(cherry picked from commit 8e7d47b3a7)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-20 15:53:20 +05:30
mergify[bot]
385b08dc50 fix: show active bom in the dropdown while making stock entry and MR (backport #39974) (#39975)
fix: show active bom in the dropdown while making stock entry and MR (#39974)

(cherry picked from commit 133f8bd92a)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-20 13:13:35 +05:30
Nabin Hait
c53ced1224 Merge pull request #39874 from nabinhait/depreciation-last-row-adjustment
fix: Adjust amount in last row due to rounding
2024-02-20 13:13:02 +05:30
Nabin Hait
a4fbea3722 fix: linter issue 2024-02-20 12:31:34 +05:30
Nabin Hait
e99485bfa7 fix: linter issues 2024-02-20 12:24:36 +05:30
Nabin Hait
963ddac528 fix: Adjust amount in last row due to rounding 2024-02-20 12:24:36 +05:30
Nabin Hait
947f138ea4 Merge pull request #39973 from nabinhait/linter-issue-1
Linter issue
2024-02-20 12:22:47 +05:30
Nabin Hait
abceb1b611 fix: linter issue 2024-02-20 12:21:12 +05:30
Nitali Mittal
d913ec52db feat: New financial views - Growth and margin views for P&L and balance sheet
feat: New financial views - Growth and margin views for P&L and balance sheet
2024-02-19 16:36:23 +05:30
ruthra kumar
e337a55a0b Merge pull request #39954 from frappe/mergify/bp/version-14-hotfix/pr-39914
refactor: add total row if only one party is being filtered (backport #39914)
2024-02-19 09:16:27 +05:30
ruthra kumar
310f338d9b Merge pull request #39952 from frappe/mergify/bp/version-14-hotfix/pr-39942
fix: group node in warehouse filter in Item-wise Sales Register (backport #39942)
2024-02-19 09:15:49 +05:30
ruthra kumar
b0c2d41ecb Merge pull request #39832 from ruthra-kumar/convert_latest_check_sql_to_qb
fix: reconciliation issue due to notation difference
2024-02-19 08:37:59 +05:30
ruthra kumar
241507a87f refactor: add total row if only one party is being filtered
(cherry picked from commit b1dfa2537b)
2024-02-19 02:56:40 +00:00
ruthra kumar
4921b038bd fix: group node in warehouse filter in Item-wise Sales Register
(cherry picked from commit 44538bd02a)
2024-02-19 02:56:18 +00:00
ruthra kumar
229e4f65b4 Merge pull request #39951 from ruthra-kumar/typerror_on_item_group_filter_in_purchase_register
fix: typerror on 'Item Group' filter on Item-Wise Purchase Register
2024-02-19 08:22:07 +05:30
ruthra kumar
a4f94ed631 Merge pull request #39949 from frappe/mergify/bp/version-14-hotfix/pr-39943
refactor: use popup to inform on additional reconciliation step for Cr/Dr Notes (backport #39943)
2024-02-19 08:21:39 +05:30
ruthra kumar
b1a4249041 fix: typeerror 'Item Group' filter on Purchase Register 2024-02-19 07:44:02 +05:30
ruthra kumar
5894bb3bbe refactor: use popup to inform on additional reconciliation step
(cherry picked from commit 0d260faa00)
2024-02-19 07:32:19 +05:30
Raffael Meyer
a83ce43845 Merge pull request #39906 from frappe/mergify/bp/version-14-hotfix/pr-39857
fix: fetch company terms (backport #39857)
2024-02-17 01:26:33 +01:00
Raffael Meyer
744de8595d Merge pull request #39927 from barredterra/bt-precision-v14 2024-02-17 00:32:15 +01:00
Raffael Meyer
e827507698 Merge pull request #39939 from frappe/mergify/bp/version-14-hotfix/pr-39938
fix(Issue): create communication (backport #39938)
2024-02-16 20:47:25 +01:00
barredterra
8deaba8def fix(Issue): create communication
Ignore permisions and mandatory. Required, for example, when Issue is created by Customer via portal.

(cherry picked from commit 3f1d008741)
2024-02-16 19:15:29 +00:00
barredterra
cea0e1fb91 fix(Bank Transaction): precision for (un)allocated_amount
Manual Backport of #39926
2024-02-15 19:58:16 +01:00
rohitwaghchaure
51dc3f57e1 Merge pull request #39917 from frappe/mergify/bp/version-14-hotfix/pr-39905
fix: party item code in Blanket Order (backport #39905)
2024-02-15 17:56:34 +05:30
rohitwaghchaure
ca8fb17ee8 chore: fix conflicts 2024-02-15 17:32:34 +05:30
rohitwaghchaure
1cca51afc6 chore: fix linter issue
(cherry picked from commit 230a7d8d53)
2024-02-15 09:33:41 +00:00
Rohit Waghchaure
ee9a51f93f fix: party item code in Blanket Order
(cherry picked from commit 1a8f7f9403)

# Conflicts:
#	erpnext/manufacturing/doctype/blanket_order_item/blanket_order_item.py
2024-02-15 09:33:40 +00:00
kunhi
5eaa11b9e8 fix: update_dimension is required and not need party account method
(cherry picked from commit e6949d71f6)
2024-02-14 14:54:44 +00:00
kunhi
45a0494318 fix: no need call for company method in sales invoice js
(cherry picked from commit e3bd8d10b0)
2024-02-14 14:54:44 +00:00
kunhi
83bf28616e fix: fetch company terms
(cherry picked from commit d97b6d38ef)
2024-02-14 14:54:43 +00:00
Frappe PR Bot
22ace5cb5a chore(release): Bumped to Version 14.62.4
## [14.62.4](https://github.com/frappe/erpnext/compare/v14.62.3...v14.62.4) (2024-02-14)

### Bug Fixes

*  production plan issue with sales order (backport [#39901](https://github.com/frappe/erpnext/issues/39901)) ([#39903](https://github.com/frappe/erpnext/issues/39903)) ([ab7e323](ab7e323648))
* accommodate for default rounding method in v14 ([d6a758d](d6a758d1f4))
* broken route option in Profitability report ([f79e0d1](f79e0d1e37))
* calculate `stock_value_diff` ([8f58b61](8f58b613e4))
* cancel asset capitalization ([2438600](24386006d6))
* do not throw validation for canceled SLE (backport [#39769](https://github.com/frappe/erpnext/issues/39769)) ([#39810](https://github.com/frappe/erpnext/issues/39810)) ([2885b8f](2885b8fa44))
* Handling circular linking while cancelling asset capitalization ([f2d094d](f2d094d1ab))
* incorrect planned qty in PP (backport [#39785](https://github.com/frappe/erpnext/issues/39785)) ([#39792](https://github.com/frappe/erpnext/issues/39792)) ([df9d52d](df9d52d3ce))
* landed cost voucher not submitting because of incorrect reference (backport [#39898](https://github.com/frappe/erpnext/issues/39898)) ([#39899](https://github.com/frappe/erpnext/issues/39899)) ([d0b9c56](d0b9c568d3))
* remove duplicates from tax category map ([c56f3a5](c56f3a58ab))
* set rate for PO created against BO (backport [#39765](https://github.com/frappe/erpnext/issues/39765)) ([#39766](https://github.com/frappe/erpnext/issues/39766)) ([de47e67](de47e67dfa))
* set route options to cost center ([#37235](https://github.com/frappe/erpnext/issues/37235)) ([79a16ba](79a16bad15))
* **ux:** set rate as price list rate on uom change in MR (backport [#39816](https://github.com/frappe/erpnext/issues/39816)) ([#39817](https://github.com/frappe/erpnext/issues/39817)) ([de6e8c7](de6e8c74c5))

### Performance Improvements

* cached get_last_purchase_details to fix performance issue (backport [#39854](https://github.com/frappe/erpnext/issues/39854)) ([#39855](https://github.com/frappe/erpnext/issues/39855)) ([08e0271](08e02710cd))
* production plan submission (backport [#39846](https://github.com/frappe/erpnext/issues/39846)) ([#39859](https://github.com/frappe/erpnext/issues/39859)) ([a61cffd](a61cffd7c2))
2024-02-14 12:06:19 +00:00
rohitwaghchaure
4fd7b01beb Merge pull request #39881 from frappe/version-14-hotfix
chore: release v14
2024-02-14 17:34:41 +05:30
mergify[bot]
ab7e323648 fix: production plan issue with sales order (backport #39901) (#39903)
fix:  production plan issue with sales order (#39901)

(cherry picked from commit d0df5df4a6)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-14 17:28:50 +05:30
mergify[bot]
d0b9c568d3 fix: landed cost voucher not submitting because of incorrect reference (backport #39898) (#39899)
fix: landed cost voucher not submitting because of incorrect reference (#39898)

(cherry picked from commit 6239fd704b)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-14 15:57:48 +05:30
Raffael Meyer
6b53288975 Merge pull request #39893 from frappe/mergify/bp/version-14-hotfix/pr-39868
fix(Purchase Receipt): calculate `stock_value_diff` (backport #39868)
2024-02-14 01:22:09 +01:00
barredterra
8f58b613e4 fix: calculate stock_value_diff
`d.item_tax_amount` is already in base currency.

(cherry picked from commit 5df5851798)
2024-02-13 23:52:34 +00:00
Nabin Hait
6460e649a5 Merge pull request #39814 from nabinhait/asset-capitalization-cancellation
fix: Handling circular linking while cancelling asset capitalization
2024-02-13 09:46:31 +05:30
mergify[bot]
a61cffd7c2 perf: production plan submission (backport #39846) (#39859)
perf: production plan submission

(cherry picked from commit aa1c69dd7a)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-12 18:17:49 +05:30
mergify[bot]
08e02710cd perf: cached get_last_purchase_details to fix performance issue (backport #39854) (#39855)
perf: cached get_last_purchase_details to fix performance issue (#39854)

(cherry picked from commit b966c06a4f)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-02-12 15:54:03 +05:30
Nabin Hait
24386006d6 fix: cancel asset capitalization 2024-02-12 11:44:41 +05:30
mergify[bot]
de6e8c74c5 fix(ux): set rate as price list rate on uom change in MR (backport #39816) (#39817)
* fix: add price list rate field in MR Item

(cherry picked from commit 61a29eb5fb)

# Conflicts:
#	erpnext/stock/doctype/material_request_item/material_request_item.py

* fix: set rate as price list rate on uom change

(cherry picked from commit 5cf0759b0c)

* chore: linter

(cherry picked from commit 1745371cd6)

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-11 17:38:37 +05:30
mergify[bot]
79a16bad15 fix: set route options to cost center (#37235)
fix: set route to cost center

cost center mapping is not correct

(cherry picked from commit 5e4b73918d)

Co-authored-by: NIYAZ RAZAK <76736615+niyazrazak@users.noreply.github.com>
2024-02-11 17:19:59 +05:30
ruthra kumar
dcf19c3ed9 fix: reconciliation issue due to notation difference 2024-02-09 16:50:14 +05:30
ruthra kumar
157d17d0f3 Merge pull request #39808 from ruthra-kumar/dimension_filter_issue_in_profitability_report
fix: incorrect route options on Profitability to Profit and Loss report
2024-02-08 15:53:26 +05:30
Nabin Hait
f2d094d1ab fix: Handling circular linking while cancelling asset capitalization 2024-02-08 15:51:29 +05:30
Frappe PR Bot
8caf655529 chore(release): Bumped to Version 14.62.3
## [14.62.3](https://github.com/frappe/erpnext/compare/v14.62.2...v14.62.3) (2024-02-08)

### Bug Fixes

* do not throw validation for canceled SLE (backport [#39769](https://github.com/frappe/erpnext/issues/39769)) ([#39810](https://github.com/frappe/erpnext/issues/39810)) ([d6054db](d6054dbdbd))
2024-02-08 09:12:55 +00:00
rohitwaghchaure
408d026465 Merge pull request #39812 from frappe/mergify/bp/version-14/pr-39810
fix: do not throw validation for canceled SLE (backport #39769) (backport #39810)
2024-02-08 14:41:43 +05:30
mergify[bot]
d6054dbdbd fix: do not throw validation for canceled SLE (backport #39769) (#39810)
fix: do not throw validation for cancelled sle

(cherry picked from commit 32ccf3524a)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
(cherry picked from commit 2885b8fa44)
2024-02-08 08:50:17 +00:00
mergify[bot]
2885b8fa44 fix: do not throw validation for canceled SLE (backport #39769) (#39810)
fix: do not throw validation for cancelled sle

(cherry picked from commit 32ccf3524a)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-02-08 14:18:50 +05:30
ruthra kumar
f79e0d1e37 fix: broken route option in Profitability report 2024-02-08 13:22:55 +05:30
rohitwaghchaure
a9c95567cb Merge pull request #39790 from aynugek/patch-2
refactor: Clean up code used to fetch website item stock details
2024-02-08 11:06:20 +05:30
ruthra kumar
28b0e988db Merge pull request #39798 from frappe/mergify/bp/version-14-hotfix/pr-39783
fix: cancelling cr/dr notes should update the linked Invoice status (backport #39783)
2024-02-08 10:00:54 +05:30
ruthra kumar
8d9b5764dd refactor(test): Forex Credit Note cancellation against Invoice
(cherry picked from commit 2f676ced5c)
2024-02-07 15:00:47 +00:00
ruthra kumar
dd74728568 refactor(test): assert Invoice status as well
(cherry picked from commit 33efe0d12d)
2024-02-07 15:00:47 +00:00
ruthra kumar
e97f30d8e2 test: Invoice status on Cr/Dr note cancellation
(cherry picked from commit 31a8c3bdc4)
2024-02-07 15:00:46 +00:00
ruthra kumar
33777a4d4c refactor: cancel Cr/Dr JE's on Sales/Purchase return cancel
(cherry picked from commit 0549535603)
2024-02-07 15:00:44 +00:00
Gursheen Kaur Anand
d62db9bb22 Merge pull request #39789 from GursheenK/duplicates-in-tax-category-bpv14
fix: remove duplicates from tax category map
2024-02-07 19:51:51 +05:30
mergify[bot]
df9d52d3ce fix: incorrect planned qty in PP (backport #39785) (#39792)
fix: incorrect planned qty in PP

(cherry picked from commit a8ebc94a36)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-07 19:26:14 +05:30
Gursheen Anand
d6a758d1f4 fix: accommodate for default rounding method in v14 2024-02-07 19:12:32 +05:30
mergify[bot]
de47e67dfa fix: set rate for PO created against BO (backport #39765) (#39766)
* fix: set rate for PO created against BO

(cherry picked from commit 0e5b4e5f07)

# Conflicts:
#	erpnext/manufacturing/doctype/blanket_order/blanket_order.py

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-02-07 19:03:38 +05:30
Gursheen Anand
c56f3a58ab fix: remove duplicates from tax category map 2024-02-07 18:46:07 +05:30
Babuuu
e3591270c6 refactor: Clean up code used to fetch website item stock details 2024-02-07 13:12:14 +00:00
41 changed files with 335 additions and 87 deletions

View File

@@ -3,7 +3,7 @@ import inspect
import frappe
__version__ = "14.62.2"
__version__ = "14.63.2"
def get_default_company(user=None):

View File

@@ -41,9 +41,10 @@ class BankTransaction(StatusUpdater):
else:
allocated_amount = 0.0
amount = abs(flt(self.withdrawal) - flt(self.deposit))
self.db_set("allocated_amount", flt(allocated_amount))
self.db_set("unallocated_amount", amount - flt(allocated_amount))
unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - allocated_amount
self.db_set("allocated_amount", flt(allocated_amount, self.precision("allocated_amount")))
self.db_set("unallocated_amount", flt(unallocated_amount, self.precision("unallocated_amount")))
self.reload()
self.set_status(update=True)

View File

@@ -11,23 +11,8 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
super.setup(doc);
}
company() {
super.company();
erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);
let me = this;
if (this.frm.doc.company) {
frappe.call({
method:
"erpnext.accounts.party.get_party_account",
args: {
party_type: 'Customer',
party: this.frm.doc.customer,
company: this.frm.doc.company
},
callback: (response) => {
if (response) me.frm.set_value("debit_to", response.message);
},
});
}
}
onload() {
var me = this;

View File

@@ -85,7 +85,10 @@ class ReceivablePayableReport(object):
self.skip_total_row = 1
if self.filters.get("in_party_currency"):
self.skip_total_row = 1
if self.filters.get("party") and len(self.filters.get("party")) == 1:
self.skip_total_row = 0
else:
self.skip_total_row = 1
def get_data(self):
self.get_ple_entries()

View File

@@ -6,6 +6,19 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
erpnext.utils.add_dimensions('Balance Sheet', 10);
frappe.query_reports["Balance Sheet"]["filters"].push(
{
"fieldname": "selected_view",
"label": __("Select View"),
"fieldtype": "Select",
"options": [
{ "value": "Report", "label": __("Report View") },
{ "value": "Growth", "label": __("Growth View") }
],
"default": "Report",
"reqd": 1
},
);
frappe.query_reports["Balance Sheet"]["filters"].push({
"fieldname": "accumulated_values",
"label": __("Accumulated Values"),

View File

@@ -319,7 +319,8 @@ def get_items(filters, additional_query_columns):
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
`tabPurchase Invoice`.unrealized_profit_loss_account,
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
`tabPurchase Invoice Item`.`item_name` as pi_item_name, `tabPurchase Invoice Item`.`item_group` as pi_item_group,
`tabPurchase Invoice Item`.`item_name` as pi_item_name, `tabPurchase Invoice Item`.`item_group`
,`tabPurchase Invoice Item`.`item_group` as pi_item_group,
`tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group,
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,

View File

@@ -350,7 +350,13 @@ def get_conditions(filters, additional_conditions=None):
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
if filters.get("warehouse"):
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
if frappe.db.get_value("Warehouse", filters.get("warehouse"), "is_group"):
lft, rgt = frappe.db.get_all(
"Warehouse", filters={"name": filters.get("warehouse")}, fields=["lft", "rgt"], as_list=True
)[0]
conditions += f"and ifnull(`tabSales Invoice Item`.warehouse, '') in (select name from `tabWarehouse` where lft > {lft} and rgt < {rgt}) "
else:
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
if filters.get("brand"):
conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""

View File

@@ -8,6 +8,21 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
erpnext.utils.add_dimensions('Profit and Loss Statement', 10);
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
{
"fieldname": "selected_view",
"label": __("Select View"),
"fieldtype": "Select",
"options": [
{ "value": "Report", "label": __("Report View") },
{ "value": "Growth", "label": __("Growth View") },
{ "value": "Margin", "label": __("Margin View") },
],
"default": "Report",
"reqd": 1
},
);
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
{
"fieldname": "include_default_book_entries",

View File

@@ -105,7 +105,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"to_fiscal_year": data.fiscal_year
};
if(data.based_on == 'cost_center'){
if(data.based_on == 'Cost Center'){
frappe.route_options["cost_center"] = data.account
} else {
frappe.route_options["project"] = data.account

View File

@@ -10,7 +10,7 @@ import frappe.defaults
from frappe import _, qb, throw
from frappe.model.meta import get_field_precision
from frappe.query_builder import AliasedQuery, Criterion, Table
from frappe.query_builder.functions import Sum
from frappe.query_builder.functions import Round, Sum
from frappe.query_builder.utils import DocType
from frappe.utils import (
cint,
@@ -549,16 +549,19 @@ def check_if_advance_entry_modified(args):
args,
)
else:
ret = frappe.db.sql(
"""select name from `tabPayment Entry`
where
name = %(voucher_no)s and docstatus = 1
and party_type = %(party_type)s and party = %(party)s and {0} = %(account)s
and round(unallocated_amount, {1}) = round(%(unreconciled_amount)s, {1})
""".format(
party_account_field, precision
),
args,
pe = qb.DocType("Payment Entry")
ret = (
qb.from_(pe)
.select(pe.name)
.where(
(pe.name == args.voucher_no)
& (pe.docstatus == 1)
& (pe.party_type == args.party_type)
& (pe.party == args.party)
& (pe[party_account_field] == args.account)
& (Round(pe.unallocated_amount, precision) == Round(args.unreconciled_amount, precision))
)
.run()
)
if not ret:

View File

@@ -322,7 +322,7 @@ frappe.ui.form.on('Asset', {
},
make_schedules_editable: function(frm) {
if (frm.doc.finance_books.length) {
if (frm.doc.finance_books && frm.doc.finance_books.length) {
var is_manual_hence_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0
? true : false;
var is_shift_hence_editable = frm.doc.finance_books.filter(d => d.shift_based).length > 0

View File

@@ -513,14 +513,15 @@ class Asset(AccountsController):
)
# Adjust depreciation amount in the last period based on the expected value after useful life
if finance_book.expected_value_after_useful_life and (
(
n == cint(final_number_of_depreciations) - 1
and value_after_depreciation != finance_book.expected_value_after_useful_life
)
or value_after_depreciation < finance_book.expected_value_after_useful_life
if (
n == cint(final_number_of_depreciations) - 1
and flt(value_after_depreciation) != flt(finance_book.expected_value_after_useful_life)
) or flt(value_after_depreciation) < flt(
finance_book.expected_value_after_useful_life
):
depreciation_amount += value_after_depreciation - finance_book.expected_value_after_useful_life
depreciation_amount += flt(value_after_depreciation) - flt(
finance_book.expected_value_after_useful_life
)
skip_row = True
if flt(depreciation_amount, self.precision("gross_purchase_amount")) > 0:

View File

@@ -508,7 +508,7 @@ def modify_depreciation_schedule_for_asset_repairs(asset):
def reverse_depreciation_entry_made_after_disposal(asset, date):
if not asset.calculate_depreciation:
if not asset.calculate_depreciation or not asset.get("schedules"):
return
row = -1
@@ -520,7 +520,7 @@ def reverse_depreciation_entry_made_after_disposal(asset, date):
else:
row += 1
if schedule.schedule_date == date:
if schedule.schedule_date == date and schedule.journal_entry:
if not disposal_was_made_on_original_schedule_date(
asset, schedule, row, date
) or disposal_happens_in_the_future(date):

View File

@@ -7,6 +7,7 @@ frappe.provide("erpnext.assets");
erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.stock.StockController {
setup() {
this.setup_posting_date_time_check();
this.frm.ignore_doctypes_on_cancel_all = ["Asset Movement"];
}
onload() {

View File

@@ -77,6 +77,7 @@ class AssetCapitalization(StockController):
"Stock Ledger Entry",
"Repost Item Valuation",
"Asset",
"Asset Movement",
)
self.cancel_target_asset()
self.update_stock_ledger()
@@ -86,6 +87,7 @@ class AssetCapitalization(StockController):
def cancel_target_asset(self):
if self.entry_type == "Capitalization" and self.target_asset:
asset_doc = frappe.get_doc("Asset", self.target_asset)
asset_doc.db_set("capitalized_in", None)
if asset_doc.docstatus == 1:
asset_doc.cancel()

View File

@@ -201,6 +201,18 @@ class AccountsController(TransactionBase):
)
)
if self.get("is_return") and self.get("return_against"):
document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note"
frappe.msgprint(
_(
"{0} will be treated as a standalone {0}. Post creation use {1} tool to reconcile against {2}."
).format(
document_type,
get_link_to_form("Payment Reconciliation", "Payment Reconciliation"),
get_link_to_form(self.doctype, self.get("return_against")),
)
)
pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
self.set_advances()

View File

@@ -190,8 +190,8 @@ class BuyingController(SubcontractingController):
lc_voucher_data = frappe.db.sql(
"""select sum(applicable_charges), cost_center
from `tabLanded Cost Item`
where docstatus = 1 and purchase_receipt_item = %s""",
d.name,
where docstatus = 1 and purchase_receipt_item = %s and receipt_document = %s""",
(d.name, self.name),
)
d.landed_cost_voucher_amount = lc_voucher_data[0][0] if lc_voucher_data else 0.0
if not d.cost_center and lc_voucher_data and lc_voucher_data[0][1]:

View File

@@ -831,6 +831,9 @@ class StockController(AccountsController):
"Stock Reconciliation",
)
if not frappe.get_all("Putaway Rule", limit=1):
return
if self.doctype == "Purchase Invoice" and self.get("update_stock") == 0:
valid_doctype = False

View File

@@ -16,11 +16,49 @@ class BlanketOrder(Document):
def validate(self):
self.validate_dates()
self.validate_duplicate_items()
self.set_party_item_code()
def validate_dates(self):
if getdate(self.from_date) > getdate(self.to_date):
frappe.throw(_("From date cannot be greater than To date"))
def set_party_item_code(self):
item_ref = {}
if self.blanket_order_type == "Selling":
item_ref = self.get_customer_items_ref()
else:
item_ref = self.get_supplier_items_ref()
if not item_ref:
return
for row in self.items:
row.party_item_code = item_ref.get(row.item_code)
def get_customer_items_ref(self):
items = [d.item_code for d in self.items]
return frappe._dict(
frappe.get_all(
"Item Customer Detail",
filters={"parent": ("in", items), "customer_name": self.customer},
fields=["parent", "ref_code"],
as_list=True,
)
)
def get_supplier_items_ref(self):
items = [d.item_code for d in self.items]
return frappe._dict(
frappe.get_all(
"Item Supplier",
filters={"parent": ("in", items), "supplier": self.supplier},
fields=["parent", "supplier_part_no"],
as_list=True,
)
)
def validate_duplicate_items(self):
item_list = []
for item in self.items:
@@ -65,6 +103,7 @@ def make_order(source_name):
def update_item(source, target, source_parent):
target_qty = source.get("qty") - source.get("ordered_qty")
target.qty = target_qty if not flt(target_qty) < 0 else 0
target.rate = source.get("rate")
item = get_item_defaults(target.item_code, source_parent.company)
if item:
target.item_name = item.get("item_name")
@@ -86,6 +125,10 @@ def make_order(source_name):
},
},
)
if target_doc.doctype == "Purchase Order":
target_doc.set_missing_values()
return target_doc

View File

@@ -5,6 +5,7 @@ from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_months, today
from erpnext import get_company_currency
from erpnext.stock.doctype.item.test_item import make_item
from .blanket_order import make_order
@@ -90,6 +91,30 @@ class TestBlanketOrder(FrappeTestCase):
frappe.db.set_single_value("Buying Settings", "blanket_order_allowance", 10)
po.submit()
def test_party_item_code(self):
item_doc = make_item("_Test Item 1 for Blanket Order")
item_code = item_doc.name
customer = "_Test Customer"
supplier = "_Test Supplier"
if not frappe.db.exists(
"Item Customer Detail", {"customer_name": customer, "parent": item_code}
):
item_doc.append("customer_items", {"customer_name": customer, "ref_code": "CUST-REF-1"})
item_doc.save()
if not frappe.db.exists("Item Supplier", {"supplier": supplier, "parent": item_code}):
item_doc.append("supplier_items", {"supplier": supplier, "supplier_part_no": "SUPP-PART-1"})
item_doc.save()
# Blanket Order for Selling
bo = make_blanket_order(blanket_order_type="Selling", customer=customer, item_code=item_code)
self.assertEqual(bo.items[0].party_item_code, "CUST-REF-1")
bo = make_blanket_order(blanket_order_type="Purchasing", supplier=supplier, item_code=item_code)
self.assertEqual(bo.items[0].party_item_code, "SUPP-PART-1")
def make_blanket_order(**args):
args = frappe._dict(args)

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"creation": "2018-05-24 07:20:04.255236",
"doctype": "DocType",
"editable_grid": 1,
@@ -6,6 +7,7 @@
"field_order": [
"item_code",
"item_name",
"party_item_code",
"column_break_3",
"qty",
"rate",
@@ -62,10 +64,17 @@
"fieldname": "terms_and_conditions",
"fieldtype": "Text",
"label": "Terms and Conditions"
},
{
"fieldname": "party_item_code",
"fieldtype": "Data",
"label": "Party Item Code",
"read_only": 1
}
],
"istable": 1,
"modified": "2019-11-18 19:37:46.245878",
"links": [],
"modified": "2024-02-14 18:25:26.479672",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Blanket Order Item",
@@ -74,5 +83,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -38,7 +38,8 @@
"in_list_view": 1,
"label": "Item Code",
"options": "Item",
"reqd": 1
"reqd": 1,
"search_index": 1
},
{
"fieldname": "item_name",
@@ -53,7 +54,8 @@
"in_standard_filter": 1,
"label": "For Warehouse",
"options": "Warehouse",
"reqd": 1
"reqd": 1,
"search_index": 1
},
{
"columns": 1,
@@ -141,7 +143,8 @@
"fieldname": "from_warehouse",
"fieldtype": "Link",
"label": "From Warehouse",
"options": "Warehouse"
"options": "Warehouse",
"search_index": 1
},
{
"fetch_from": "item_code.safety_stock",
@@ -199,7 +202,7 @@
],
"istable": 1,
"links": [],
"modified": "2023-09-12 12:09:08.358326",
"modified": "2024-02-11 16:21:11.977018",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Material Request Plan Item",

View File

@@ -298,7 +298,8 @@
"no_copy": 1,
"options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nClosed\nCancelled\nMaterial Requested",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "amended_from",
@@ -436,7 +437,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-12-26 16:31:13.740777",
"modified": "2024-02-11 15:42:47.642481",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan",

View File

@@ -576,7 +576,10 @@ class ProductionPlan(Document):
"project": self.project,
}
key = (d.item_code, d.sales_order, d.warehouse)
key = (d.item_code, d.sales_order, d.sales_order_item, d.warehouse)
if self.combine_items:
key = (d.item_code, d.sales_order, d.warehouse)
if not d.sales_order:
key = (d.name, d.item_code, d.warehouse)
@@ -1691,23 +1694,23 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
return reserved_qty_for_production_plan - reserved_qty_for_production
@frappe.request_cache
def get_non_completed_production_plans():
table = frappe.qb.DocType("Production Plan")
child = frappe.qb.DocType("Production Plan Item")
query = (
return (
frappe.qb.from_(table)
.inner_join(child)
.on(table.name == child.parent)
.select(table.name)
.distinct()
.where(
(table.docstatus == 1)
& (table.status.notin(["Completed", "Closed"]))
& (child.planned_qty > child.ordered_qty)
)
).run(as_dict=True)
return list(set([d.name for d in query]))
).run(pluck="name")
def get_raw_materials_of_sub_assembly_items(

View File

@@ -448,7 +448,8 @@
"no_copy": 1,
"options": "Production Plan",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "production_plan_item",
@@ -600,7 +601,7 @@
"image_field": "image",
"is_submittable": 1,
"links": [],
"modified": "2023-08-11 18:35:49.852069",
"modified": "2024-02-11 15:47:13.454422",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order",

View File

@@ -36,7 +36,8 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Item Code",
"options": "Item"
"options": "Item",
"search_index": 1
},
{
"fieldname": "source_warehouse",
@@ -141,7 +142,7 @@
],
"istable": 1,
"links": [],
"modified": "2022-09-28 10:50:43.512562",
"modified": "2024-02-11 15:45:32.318374",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order Item",

View File

@@ -2,7 +2,57 @@ frappe.provide("erpnext.financial_statements");
erpnext.financial_statements = {
"filters": get_filters(),
"baseData": null,
"formatter": function(value, row, column, data, default_formatter, filter) {
if(frappe.query_report.get_filter_value("selected_view") == "Growth" && data && column.colIndex >= 3){
//Assuming that the first three columns are s.no, account name and the very first year of the accounting values, to calculate the relative percentage values of the successive columns.
const lastAnnualValue = row[column.colIndex - 1].content;
const currentAnnualvalue = data[column.fieldname];
if(currentAnnualvalue == undefined) return 'NA'; //making this not applicable for undefined/null values
let annualGrowth = 0;
if(lastAnnualValue == 0 && currentAnnualvalue > 0){
//If the previous year value is 0 and the current value is greater than 0
annualGrowth = 1;
}
else if(lastAnnualValue > 0){
annualGrowth = (currentAnnualvalue - lastAnnualValue) / lastAnnualValue;
}
const growthPercent = (Math.round(annualGrowth*10000)/100); //calculating the rounded off percentage
value = $(`<span>${((growthPercent >=0)? '+':'' )+growthPercent+'%'}</span>`);
if(growthPercent < 0){
value = $(value).addClass("text-danger");
}
else{
value = $(value).addClass("text-success");
}
value = $(value).wrap("<p></p>").parent().html();
return value;
}
else if(frappe.query_report.get_filter_value("selected_view") == "Margin" && data){
if(column.fieldname =="account" && data.account_name == __("Income")){
//Taking the total income from each column (for all the financial years) as the base (100%)
this.baseData = row;
}
if(column.colIndex >= 2){
//Assuming that the first two columns are s.no and account name, to calculate the relative percentage values of the successive columns.
const currentAnnualvalue = data[column.fieldname];
const baseValue = this.baseData[column.colIndex].content;
if(currentAnnualvalue == undefined || baseValue <= 0) return 'NA';
const marginPercent = Math.round((currentAnnualvalue/baseValue)*10000)/100;
value = $(`<span>${marginPercent+'%'}</span>`);
if(marginPercent < 0)
value = $(value).addClass("text-danger");
else
value = $(value).addClass("text-success");
value = $(value).wrap("<p></p>").parent().html();
return value;
}
}
if (data && column.fieldname=="account") {
value = data.account_name || value;

View File

@@ -1,5 +1,6 @@
{
"actions": [],
"allow_guest_to_view": 1,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:item_group_name",
@@ -227,13 +228,14 @@
"label": "Include Descendants"
}
],
"has_web_view": 1,
"icon": "fa fa-sitemap",
"idx": 1,
"image_field": "image",
"is_tree": 1,
"links": [],
"max_attachments": 3,
"modified": "2023-01-05 12:21:30.458628",
"modified": "2024-02-22 16:23:46.936496",
"modified_by": "Administrator",
"module": "Setup",
"name": "Item Group",

View File

@@ -0,0 +1,7 @@
{% extends "templates/web.html" %}
{% block page_content %}
<h1>{{ title }}</h1>
{% endblock %}
<!-- this is a sample default web page template -->

View File

@@ -0,0 +1,4 @@
<div>
<a href="{{ doc.route }}">{{ doc.title or doc.name }}</a>
</div>
<!-- this is a sample default list template -->

View File

@@ -1047,6 +1047,7 @@ def validate_cancelled_item(item_code, docstatus=None):
frappe.throw(_("Item {0} is cancelled").format(item_code))
@frappe.request_cache
def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
"""returns last purchase details in stock uom"""
# get last purchase order item details

View File

@@ -38,6 +38,7 @@ class LandedCostVoucher(Document):
def validate(self):
self.check_mandatory()
self.validate_receipt_documents()
self.validate_line_items()
init_landed_taxes_and_totals(self)
self.set_total_taxes_and_charges()
if not self.get("items"):
@@ -45,6 +46,26 @@ class LandedCostVoucher(Document):
self.set_applicable_charges_on_item()
def validate_line_items(self):
for d in self.get("items"):
if (
d.docstatus == 0
and d.purchase_receipt_item
and not frappe.db.exists(
d.receipt_document_type + " Item",
{"name": d.purchase_receipt_item, "parent": d.receipt_document},
)
):
frappe.throw(
_("Row {0}: {2} Item {1} does not exist in {2} {3}").format(
d.idx,
frappe.bold(d.purchase_receipt_item),
d.receipt_document_type,
frappe.bold(d.receipt_document),
),
title=_("Incorrect Reference Document (Purchase Receipt Item)"),
)
def check_mandatory(self):
if not self.get("purchase_receipts"):
frappe.throw(_("Please enter Receipt Document"))

View File

@@ -228,9 +228,17 @@ frappe.ui.form.on('Material Request', {
const qty_fields = ['actual_qty', 'projected_qty', 'min_order_qty'];
if(!r.exc) {
$.each(r.message, function(k, v) {
if(!d[k] || in_list(qty_fields, k)) d[k] = v;
$.each(r.message, function(key, value) {
if(!d[key] || qty_fields.includes(key)) {
d[key] = value;
}
});
if (d.price_list_rate != r.message.price_list_rate) {
d.price_list_rate = r.message.price_list_rate;
frappe.model.set_value(d.doctype, d.name, "rate", d.price_list_rate);
}
}
}
});
@@ -242,7 +250,7 @@ frappe.ui.form.on('Material Request', {
fields: [
{"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"),
options:"BOM", reqd: 1, get_query: function() {
return {filters: { docstatus:1 }};
return {filters: { docstatus:1, "is_active": 1 }};
}},
{"fieldname":"warehouse", "fieldtype":"Link", "label":__("For Warehouse"),
options:"Warehouse", reqd: 1},
@@ -432,7 +440,6 @@ frappe.ui.form.on("Material Request Item", {
item.amount = flt(item.qty) * flt(item.rate);
frappe.model.set_value(doctype, name, "amount", item.amount);
refresh_field("amount", item.name, item.parentfield);
frm.events.get_item_data(frm, item, false);
},
item_code: function(frm, doctype, name) {
@@ -452,7 +459,12 @@ frappe.ui.form.on("Material Request Item", {
set_schedule_date(frm);
}
}
}
},
conversion_factor: function(frm, doctype, name) {
const item = locals[doctype][name];
frm.events.get_item_data(frm, item, false);
},
});
erpnext.buying.MaterialRequestController = class MaterialRequestController extends erpnext.buying.BuyingController {

View File

@@ -35,6 +35,7 @@
"received_qty",
"rate_and_amount_section_break",
"rate",
"price_list_rate",
"col_break3",
"amount",
"accounting_details_section",
@@ -474,13 +475,22 @@
"fieldtype": "Link",
"label": "WIP Composite Asset",
"options": "Asset"
},
{
"fieldname": "price_list_rate",
"fieldtype": "Currency",
"hidden": 1,
"label": "Price List Rate",
"options": "currency",
"print_hide": 1,
"read_only": 1
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-11-14 18:37:59.599115",
"modified": "2024-02-08 16:30:56.137858",
"modified_by": "Administrator",
"module": "Stock",
"name": "Material Request Item",

View File

@@ -32,6 +32,10 @@ class PickList(Document):
self.update_status()
self.set_item_locations()
if self.get("locations"):
self.validate_sales_order_percentage()
def validate_sales_order_percentage(self):
# set percentage picked in SO
for location in self.get("locations"):
if (

View File

@@ -572,9 +572,7 @@ class PurchaseReceipt(BuyingController):
)
stock_value_diff = (
flt(d.base_net_amount)
+ flt(d.item_tax_amount / self.conversion_rate)
+ flt(d.landed_cost_voucher_amount)
flt(d.base_net_amount) + flt(d.item_tax_amount) + flt(d.landed_cost_voucher_amount)
)
elif warehouse_account.get(d.warehouse):
stock_value_diff = get_stock_value_difference(self.name, d.name, d.warehouse)

View File

@@ -548,7 +548,9 @@ frappe.ui.form.on('Stock Entry', {
let fields = [
{"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"),
options:"BOM", reqd: 1, get_query: filters()},
options:"BOM", reqd: 1, get_query: () => {
return {filters: { docstatus:1, "is_active": 1 }};
}},
{"fieldname":"source_warehouse", "fieldtype":"Link", "label":__("Source Warehouse"),
options:"Warehouse"},
{"fieldname":"target_warehouse", "fieldtype":"Link", "label":__("Target Warehouse"),

View File

@@ -53,6 +53,9 @@ class StockLedgerEntry(Document):
self.validate_inventory_dimension_negative_stock()
def validate_inventory_dimension_negative_stock(self):
if self.is_cancelled:
return
extra_cond = ""
kwargs = {}

View File

@@ -699,8 +699,13 @@ class StockReconciliation(StockController):
def has_negative_stock_allowed(self):
allow_negative_stock = cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock"))
if allow_negative_stock:
return True
if all(d.batch_no and flt(d.qty) == flt(d.current_qty) for d in self.items):
if any(
(d.batch_no and flt(d.qty) == flt(d.current_qty))
for d in self.items
):
allow_negative_stock = True
return allow_negative_stock

View File

@@ -72,8 +72,8 @@ class Issue(Document):
"reference_name": self.name,
}
)
communication.ignore_permissions = True
communication.ignore_mandatory = True
communication.flags.ignore_permissions = True
communication.flags.ignore_mandatory = True
communication.save()
@frappe.whitelist()

View File

@@ -11,7 +11,6 @@ from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
in_stock, stock_qty = 0, ""
template_item_code, is_stock_item = frappe.db.get_value(
"Item", item_code, ["variant_of", "is_stock_item"]
)
@@ -53,9 +52,10 @@ def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
).run()
if stock_qty:
stock_qty = flt(stock_qty[0][0])
total_stock += adjust_qty_for_expired_items(item_code, stock_qty, warehouse)
in_stock = total_stock > 0 and 1 or 0
in_stock = int(total_stock > 0)
return frappe._dict(
{"in_stock": in_stock, "stock_qty": total_stock, "is_stock_item": is_stock_item}
@@ -63,20 +63,16 @@ def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
def adjust_qty_for_expired_items(item_code, stock_qty, warehouse):
batches = frappe.get_all("Batch", filters=[{"item": item_code}], fields=["expiry_date", "name"])
batches = frappe.get_all("Batch", filters={"item": item_code}, fields=["expiry_date", "name"])
expired_batches = get_expired_batches(batches)
stock_qty = [list(item) for item in stock_qty]
for batch in expired_batches:
if warehouse:
stock_qty[0][0] = max(0, stock_qty[0][0] - get_batch_qty(batch, warehouse))
stock_qty = max(0, stock_qty - get_batch_qty(batch, warehouse))
else:
stock_qty[0][0] = max(0, stock_qty[0][0] - qty_from_all_warehouses(get_batch_qty(batch)))
stock_qty = max(0, stock_qty - qty_from_all_warehouses(get_batch_qty(batch)))
if not stock_qty[0][0]:
break
return stock_qty[0][0] if stock_qty else 0
return stock_qty
def get_expired_batches(batches):