mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-18 12:39:18 +00:00
Compare commits
102 Commits
revert-297
...
v13.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2b5562a3f | ||
|
|
eee03fcbab | ||
|
|
d7c4818a5d | ||
|
|
9a4926bb0d | ||
|
|
f99f872946 | ||
|
|
87b4e6ea32 | ||
|
|
cf4e29a604 | ||
|
|
4df54cc62c | ||
|
|
8492bf040d | ||
|
|
1f10a99910 | ||
|
|
9bcc402f41 | ||
|
|
5abf905ff7 | ||
|
|
478360397d | ||
|
|
5d5dc56f94 | ||
|
|
6588a936d5 | ||
|
|
9af3f12411 | ||
|
|
b4e7ee0e45 | ||
|
|
bb0b1e61d6 | ||
|
|
6eb8d19cc9 | ||
|
|
cd36ba7e64 | ||
|
|
532a224c44 | ||
|
|
67768faaef | ||
|
|
a57976660a | ||
|
|
4704003c94 | ||
|
|
b5d1a7731c | ||
|
|
7a8a449ed4 | ||
|
|
bf3e191570 | ||
|
|
b5ffaff6a8 | ||
|
|
f79a72dbf3 | ||
|
|
820a579051 | ||
|
|
4f0e6cd911 | ||
|
|
f913838373 | ||
|
|
9f305e983c | ||
|
|
ea2408744a | ||
|
|
5884f1aeb0 | ||
|
|
26bec9d7b4 | ||
|
|
6495a4d2ed | ||
|
|
94484d7766 | ||
|
|
9cab26b7bf | ||
|
|
99531a35e0 | ||
|
|
a97556fa8d | ||
|
|
24a88f6cf6 | ||
|
|
1e2df2c109 | ||
|
|
b2f2d0e749 | ||
|
|
95bc141531 | ||
|
|
433815daba | ||
|
|
4afda3c89c | ||
|
|
a717b5ad6e | ||
|
|
bbf6121bb5 | ||
|
|
ac52daa14f | ||
|
|
5ef9a62917 | ||
|
|
302855e160 | ||
|
|
c8ed863454 | ||
|
|
efd7d584b2 | ||
|
|
42d72b55b8 | ||
|
|
27299cfcc5 | ||
|
|
cd503ce01d | ||
|
|
cee0ddea78 | ||
|
|
8449a47048 | ||
|
|
4e10ce1632 | ||
|
|
0385ae2b43 | ||
|
|
8821d71094 | ||
|
|
830e87a4dd | ||
|
|
5dd92934ae | ||
|
|
d0ba0217e4 | ||
|
|
c63e233bc7 | ||
|
|
4c94ccc8d8 | ||
|
|
2df7f474fa | ||
|
|
d4dc76c3ee | ||
|
|
b084f1d320 | ||
|
|
5269f1537d | ||
|
|
753e5894de | ||
|
|
e5df60287e | ||
|
|
db95db892c | ||
|
|
8f057b4bac | ||
|
|
10085580c8 | ||
|
|
6368c976c7 | ||
|
|
6bae78f410 | ||
|
|
bc92ecb10f | ||
|
|
9ec0f11800 | ||
|
|
2f403f1bcd | ||
|
|
ad0b8fdd1e | ||
|
|
e9f6c8cdb1 | ||
|
|
0048418c46 | ||
|
|
a0a88a710e | ||
|
|
7c6de1a8ac | ||
|
|
6084baa9ae | ||
|
|
8e748f8451 | ||
|
|
c29c6ff9a7 | ||
|
|
fe68a0ff80 | ||
|
|
6578c045ca | ||
|
|
4ec0656f64 | ||
|
|
aaca8335f0 | ||
|
|
dd1822ef58 | ||
|
|
e38192cb6d | ||
|
|
ec2ba6bc1f | ||
|
|
ae18efaa0a | ||
|
|
0e41295c0e | ||
|
|
92cefd5655 | ||
|
|
daf6c124a9 | ||
|
|
be66ee9723 | ||
|
|
a0ed517c85 |
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '13.2.0'
|
||||
__version__ = '13.6.0'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
73
erpnext/change_log/v13/v13_3_0.md
Normal file
73
erpnext/change_log/v13/v13_3_0.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Version 13.3.0 Release Notes
|
||||
|
||||
### Features & Enhancements
|
||||
|
||||
- Purchase receipt creation from purchase invoice ([#25126](https://github.com/frappe/erpnext/pull/25126))
|
||||
- New Document Transaction Deletion ([#25354](https://github.com/frappe/erpnext/pull/25354))
|
||||
- Employee Referral ([#24997](https://github.com/frappe/erpnext/pull/24997))
|
||||
- Add Create Expense Claim button in Delivery Trip ([#25526](https://github.com/frappe/erpnext/pull/25526))
|
||||
- Reduced rate of asset depreciation as per IT Act ([#25648](https://github.com/frappe/erpnext/pull/25648))
|
||||
- Improve DATEV export ([#25238](https://github.com/frappe/erpnext/pull/25238))
|
||||
- Add pick batch button ([#25413](https://github.com/frappe/erpnext/pull/25413))
|
||||
- Enable custom field search on POS ([#25421](https://github.com/frappe/erpnext/pull/25421))
|
||||
- New check field in subscriptions for (not) submitting invoices ([#25394](https://github.com/frappe/erpnext/pull/25394))
|
||||
- Show POS reserved stock in stock projected qty report ([#25593](https://github.com/frappe/erpnext/pull/25593))
|
||||
- e-way bill validity field ([#25555](https://github.com/frappe/erpnext/pull/25555))
|
||||
- Significant reduction in time taken to save sales documents ([#25475](https://github.com/frappe/erpnext/pull/25475))
|
||||
|
||||
### Fixes
|
||||
|
||||
- Bank statement import via google sheet ([#25677](https://github.com/frappe/erpnext/pull/25677))
|
||||
- Invoices not getting fetched during payment reconciliation ([#25598](https://github.com/frappe/erpnext/pull/25598))
|
||||
- Error on applying TDS without party ([#25632](https://github.com/frappe/erpnext/pull/25632))
|
||||
- Allow to cancel loan with cancelled repayment entry ([#25507](https://github.com/frappe/erpnext/pull/25507))
|
||||
- Can't open general ledger from consolidated financial report ([#25542](https://github.com/frappe/erpnext/pull/25542))
|
||||
- Add 'Partially Received' to Status drop-down list in Material Request ([#24857](https://github.com/frappe/erpnext/pull/24857))
|
||||
- Updated item filters for material request ([#25531](https://github.com/frappe/erpnext/pull/25531))
|
||||
- Added validation in stock entry to check duplicate serial nos ([#25611](https://github.com/frappe/erpnext/pull/25611))
|
||||
- Update shopify api version ([#25600](https://github.com/frappe/erpnext/pull/25600))
|
||||
- Dialog variable assignment after definition in POS ([#25680](https://github.com/frappe/erpnext/pull/25680))
|
||||
- Added tax_types list ([#25587](https://github.com/frappe/erpnext/pull/25587))
|
||||
- Include search fields in Project Link field query ([#25505](https://github.com/frappe/erpnext/pull/25505))
|
||||
- Item stock levels displaying inconsistently ([#25506](https://github.com/frappe/erpnext/pull/25506))
|
||||
- Change today to now to get data for reposting ([#25703](https://github.com/frappe/erpnext/pull/25703))
|
||||
- Parameter for get_filtered_list_for_consolidated_report in consolidated balance sheet ([#25700](https://github.com/frappe/erpnext/pull/25700))
|
||||
- Minor fixes in loan ([#25546](https://github.com/frappe/erpnext/pull/25546))
|
||||
- Fieldname when updating docfield property ([#25516](https://github.com/frappe/erpnext/pull/25516))
|
||||
- Use get_serial_nos for splitting ([#25590](https://github.com/frappe/erpnext/pull/25590))
|
||||
- Show item's full name on hover over item in POS ([#25554](https://github.com/frappe/erpnext/pull/25554))
|
||||
- Stock ledger entry created against draft stock entry ([#25540](https://github.com/frappe/erpnext/pull/25540))
|
||||
- Incorrect expense account set in pos invoice ([#25543](https://github.com/frappe/erpnext/pull/25543))
|
||||
- Stock balance and batch-wise balance history report showing different closing stock ([#25575](https://github.com/frappe/erpnext/pull/25575))
|
||||
- Make strings translatable ([#25521](https://github.com/frappe/erpnext/pull/25521))
|
||||
- Serial no changed after saving stock reconciliation ([#25541](https://github.com/frappe/erpnext/pull/25541))
|
||||
- Ignore fraction difference while making round off gl entry ([#25438](https://github.com/frappe/erpnext/pull/25438))
|
||||
- Sync shopify customer addresses ([#25481](https://github.com/frappe/erpnext/pull/25481))
|
||||
- Total stock summary report not working ([#25551](https://github.com/frappe/erpnext/pull/25551))
|
||||
- Rename field has not updated value of deposit and withdrawal fields ([#25545](https://github.com/frappe/erpnext/pull/25545))
|
||||
- Unexpected keyword argument 'merge_logs' ([#25489](https://github.com/frappe/erpnext/pull/25489))
|
||||
- Validation message of quality inspection in purchase receipt ([#25667](https://github.com/frappe/erpnext/pull/25667))
|
||||
- Added is_stock_item filter ([#25530](https://github.com/frappe/erpnext/pull/25530))
|
||||
- Fetch total stock at company in PO ([#25532](https://github.com/frappe/erpnext/pull/25532))
|
||||
- Updated filters for process statement of accounts ([#25384](https://github.com/frappe/erpnext/pull/25384))
|
||||
- Incorrect expense account set in pos invoice ([#25571](https://github.com/frappe/erpnext/pull/25571))
|
||||
- Client script breaking while settings tax labels ([#25653](https://github.com/frappe/erpnext/pull/25653))
|
||||
- Empty payment term column in accounts receivable report ([#25556](https://github.com/frappe/erpnext/pull/25556))
|
||||
- Designation insufficient permission on lead doctype. ([#25331](https://github.com/frappe/erpnext/pull/25331))
|
||||
- Force https for shopify webhook registration ([#25630](https://github.com/frappe/erpnext/pull/25630))
|
||||
- Patch regional fields for old companies ([#25673](https://github.com/frappe/erpnext/pull/25673))
|
||||
- Woocommerce order sync issue ([#25692](https://github.com/frappe/erpnext/pull/25692))
|
||||
- Allow to receive same serial numbers multiple times ([#25471](https://github.com/frappe/erpnext/pull/25471))
|
||||
- Update Allocated amount after Paid Amount is changed in PE ([#25515](https://github.com/frappe/erpnext/pull/25515))
|
||||
- Updating Standard Notification's channel field ([#25564](https://github.com/frappe/erpnext/pull/25564))
|
||||
- Report summary showing inflated values when values are accumulated in Group Company ([#25577](https://github.com/frappe/erpnext/pull/25577))
|
||||
- UI fixes related to overflowing payment section ([#25652](https://github.com/frappe/erpnext/pull/25652))
|
||||
- List invoices in Payment Reconciliation Payment ([#25524](https://github.com/frappe/erpnext/pull/25524))
|
||||
- Ageing errors in PSOA ([#25490](https://github.com/frappe/erpnext/pull/25490))
|
||||
- Prevent spurious defaults for items when making prec from dnote ([#25559](https://github.com/frappe/erpnext/pull/25559))
|
||||
- Stock reconciliation getting time out error during submission ([#25557](https://github.com/frappe/erpnext/pull/25557))
|
||||
- Timesheet filter date exclusive issue ([#25626](https://github.com/frappe/erpnext/pull/25626))
|
||||
- Update cost center in the item table fetched from POS Profile ([#25609](https://github.com/frappe/erpnext/pull/25609))
|
||||
- Updated modified time in purchase invoice to pull new fields ([#25678](https://github.com/frappe/erpnext/pull/25678))
|
||||
- Stock and Accounts Settings form refactor ([#25534](https://github.com/frappe/erpnext/pull/25534))
|
||||
- Payment amount showing in foreign currency ([#25292](https://github.com/frappe/erpnext/pull/25292))
|
||||
54
erpnext/change_log/v13/v13_4_0.md
Normal file
54
erpnext/change_log/v13/v13_4_0.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Version 13.4.0 Release Notes
|
||||
|
||||
### Features & Enhancements
|
||||
|
||||
- Multiple GST enhancement and fixes ([#25249](https://github.com/frappe/erpnext/pull/25249))
|
||||
- Linking supplier with an item group for filtering items ([#25683](https://github.com/frappe/erpnext/pull/25683))
|
||||
- Leave Policy Assignment Refactor ([#24327](https://github.com/frappe/erpnext/pull/24327))
|
||||
- Dimension-wise Accounts Balance Report ([#25260](https://github.com/frappe/erpnext/pull/25260))
|
||||
- Show net values in Party Accounts ([#25714](https://github.com/frappe/erpnext/pull/25714))
|
||||
- Add pending qty section to batch/serial selector dialog ([#25519](https://github.com/frappe/erpnext/pull/25519))
|
||||
- enhancements in Training Event ([#25782](https://github.com/frappe/erpnext/pull/25782))
|
||||
- Refactored timesheet ([#25701](https://github.com/frappe/erpnext/pull/25701))
|
||||
|
||||
### Fixes
|
||||
|
||||
- Process Statement of Accounts formatting ([#25777](https://github.com/frappe/erpnext/pull/25777))
|
||||
- Removed serial no validation for sales invoice ([#25817](https://github.com/frappe/erpnext/pull/25817))
|
||||
- Fetch email id from dialog box in pos past order summary ([#25808](https://github.com/frappe/erpnext/pull/25808))
|
||||
- Don't map set warehouse from delivery note to purchase receipt ([#25672](https://github.com/frappe/erpnext/pull/25672))
|
||||
- Apply permission while selecting projects ([#25765](https://github.com/frappe/erpnext/pull/25765))
|
||||
- Error on adding bank account to plaid ([#25658](https://github.com/frappe/erpnext/pull/25658))
|
||||
- Set disable rounded total if it is globally enabled ([#25789](https://github.com/frappe/erpnext/pull/25789))
|
||||
- Wrong amount on CR side in general ledger report for customer when different account currencies are involved ([#25654](https://github.com/frappe/erpnext/pull/25654))
|
||||
- Stock move dialog duplicate submit actions (V13) ([#25486](https://github.com/frappe/erpnext/pull/25486))
|
||||
- Cashflow mapper not showing data ([#25815](https://github.com/frappe/erpnext/pull/25815))
|
||||
- Ignore rounding diff while importing JV using data import ([#25816](https://github.com/frappe/erpnext/pull/25816))
|
||||
- Woocommerce order sync issue ([#25688](https://github.com/frappe/erpnext/pull/25688))
|
||||
- Expected amount in pos closing payments table ([#25737](https://github.com/frappe/erpnext/pull/25737))
|
||||
- Show only company addresses for ITC reversal entry ([#25867](https://github.com/frappe/erpnext/pull/25867))
|
||||
- Timeout error while loading warehouse tree ([#25694](https://github.com/frappe/erpnext/pull/25694))
|
||||
- Plaid Withdrawals and Deposits are recorded incorrectly ([#25784](https://github.com/frappe/erpnext/pull/25784))
|
||||
- Return case for item with available qty equal to one ([#25760](https://github.com/frappe/erpnext/pull/25760))
|
||||
- The status of repost item valuation showing In Progress since long time ([#25754](https://github.com/frappe/erpnext/pull/25754))
|
||||
- Updated applicable charges form in landed cost voucher ([#25732](https://github.com/frappe/erpnext/pull/25732))
|
||||
- Rearrange buttons for Company DocType ([#25617](https://github.com/frappe/erpnext/pull/25617))
|
||||
- Show uom for item in selector dialog ([#25697](https://github.com/frappe/erpnext/pull/25697))
|
||||
- Warehouse not found in stock entry ([#25776](https://github.com/frappe/erpnext/pull/25776))
|
||||
- Use dictionary filter instead of list (bp #25874 pre-release) ([#25875](https://github.com/frappe/erpnext/pull/25875))
|
||||
- Send emails on rfq submit ([#25695](https://github.com/frappe/erpnext/pull/25695))
|
||||
- Cannot bypass e-invoicing for non gst item invoices ([#25759](https://github.com/frappe/erpnext/pull/25759))
|
||||
- Validation message of quality inspection in purchase receipt ([#25666](https://github.com/frappe/erpnext/pull/25666))
|
||||
- Dialog variable assignment after definition in POS ([#25681](https://github.com/frappe/erpnext/pull/25681))
|
||||
- Wrong quantity after transaction for parallel stock transactions ([#25779](https://github.com/frappe/erpnext/pull/25779))
|
||||
- Item Variant Details Report ([#25797](https://github.com/frappe/erpnext/pull/25797))
|
||||
- Duplicate stock entry on multiple click ([#25742](https://github.com/frappe/erpnext/pull/25742))
|
||||
- Bank statement import via google sheet ([#25676](https://github.com/frappe/erpnext/pull/25676))
|
||||
- Change today to now to get data for reposting ([#25702](https://github.com/frappe/erpnext/pull/25702))
|
||||
- Parameter for get_filtered_list_for_consolidated_report in consolidated balance sheet ([#25698](https://github.com/frappe/erpnext/pull/25698))
|
||||
- Ageing error in PSOA ([#25857](https://github.com/frappe/erpnext/pull/25857))
|
||||
- Breaking cost center validation ([#25660](https://github.com/frappe/erpnext/pull/25660))
|
||||
- Project filter for Kanban Board ([#25744](https://github.com/frappe/erpnext/pull/25744))
|
||||
- Show allow zero valuation only when auto checked ([#25778](https://github.com/frappe/erpnext/pull/25778))
|
||||
- Missing cost center message on creating gl entries ([#25755](https://github.com/frappe/erpnext/pull/25755))
|
||||
- Address template with upper filter throws jinja error ([#25756](https://github.com/frappe/erpnext/pull/25756))
|
||||
54
erpnext/change_log/v13/v13_5_0.md
Normal file
54
erpnext/change_log/v13/v13_5_0.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Version 13.5.0 Release Notes
|
||||
|
||||
### Features & Enhancements
|
||||
|
||||
- Tax deduction against advance payments ([#25831](https://github.com/frappe/erpnext/pull/25831))
|
||||
- Cost-center wise period closing entry ([#25766](https://github.com/frappe/erpnext/pull/25766))
|
||||
- Create Quality Inspections from account and stock documents ([#25221](https://github.com/frappe/erpnext/pull/25221))
|
||||
- Item Taxes based on net rate ([#25961](https://github.com/frappe/erpnext/pull/25961))
|
||||
- Enable/disable gl entry posting for change given in pos ([#25822](https://github.com/frappe/erpnext/pull/25822))
|
||||
- Add Inactive status to Employee ([#26029](https://github.com/frappe/erpnext/pull/26029))
|
||||
- Added check box to combine items with same BOM ([#25478](https://github.com/frappe/erpnext/pull/25478))
|
||||
- Item Tax Templates for Germany ([#25858](https://github.com/frappe/erpnext/pull/25858))
|
||||
- Refactored leave balance report ([#25771](https://github.com/frappe/erpnext/pull/25771))
|
||||
- Refactored Vehicle Expenses Report ([#25727](https://github.com/frappe/erpnext/pull/25727))
|
||||
- Refactored maintenance schedule and visit document ([#25358](https://github.com/frappe/erpnext/pull/25358))
|
||||
|
||||
### Fixes
|
||||
|
||||
- Cannot add same item with different rates ([#25849](https://github.com/frappe/erpnext/pull/25849))
|
||||
- Show only company addresses for ITC reversal entry ([#25866](https://github.com/frappe/erpnext/pull/25866))
|
||||
- Hiding Rounding Adjustment field ([#25380](https://github.com/frappe/erpnext/pull/25380))
|
||||
- Auto tax calculations in Payment Entry ([#26055](https://github.com/frappe/erpnext/pull/26055))
|
||||
- Not able to select the item code in work order ([#25915](https://github.com/frappe/erpnext/pull/25915))
|
||||
- Cannot reset plaid link for a bank account ([#25869](https://github.com/frappe/erpnext/pull/25869))
|
||||
- Student invalid password reset link ([#25826](https://github.com/frappe/erpnext/pull/25826))
|
||||
- Multiple pos issues ([#25928](https://github.com/frappe/erpnext/pull/25928))
|
||||
- Add Product Bundles to POS ([#25860](https://github.com/frappe/erpnext/pull/25860))
|
||||
- Enable Parallel tests ([#25862](https://github.com/frappe/erpnext/pull/25862))
|
||||
- Service item check on e-Invoicing ([#25986](https://github.com/frappe/erpnext/pull/25986))
|
||||
- Choose correct Salary Structure Assignment when getting data for formula eval ([#25981](https://github.com/frappe/erpnext/pull/25981))
|
||||
- Ignore internal transfer invoices from GST Reports ([#25969](https://github.com/frappe/erpnext/pull/25969))
|
||||
- Taxable value for invoices with additional discount ([#26056](https://github.com/frappe/erpnext/pull/26056))
|
||||
- Validate negative allocated amount in Payment Entry ([#25799](https://github.com/frappe/erpnext/pull/25799))
|
||||
- Allow all System Managers to delete company transactions ([#25834](https://github.com/frappe/erpnext/pull/25834))
|
||||
- Wrong round off gl entry posted in case of purchase invoice ([#25775](https://github.com/frappe/erpnext/pull/25775))
|
||||
- Use dictionary filter instead of list ([#25874](https://github.com/frappe/erpnext/pull/25874))
|
||||
- Ageing error in PSOA ([#25855](https://github.com/frappe/erpnext/pull/25855))
|
||||
- On click of duplicate button system has not copied the difference account ([#25988](https://github.com/frappe/erpnext/pull/25988))
|
||||
- Assign Product Bundle's conversion_factor to Pack… ([#25840](https://github.com/frappe/erpnext/pull/25840))
|
||||
- Rename Loan Management workspace to Loans ([#25856](https://github.com/frappe/erpnext/pull/25856))
|
||||
- Fix stock quantity calculation when negative_stock_allowe… ([#25859](https://github.com/frappe/erpnext/pull/25859))
|
||||
- Update cost center from pos profile ([#25971](https://github.com/frappe/erpnext/pull/25971))
|
||||
- Ensure website theme is applied correctly ([#25863](https://github.com/frappe/erpnext/pull/25863))
|
||||
- Only display GST card in Accounting Workspace if it's in India ([#26000](https://github.com/frappe/erpnext/pull/26000))
|
||||
- Incorrect gstin fetched incase of branch company address ([#25841](https://github.com/frappe/erpnext/pull/25841))
|
||||
- Sort account balances by account name ([#26009](https://github.com/frappe/erpnext/pull/26009))
|
||||
- Custom conversion factor field not mapped from job card to stock entry ([#25956](https://github.com/frappe/erpnext/pull/25956))
|
||||
- Chart of accounts importer always error ([#25882](https://github.com/frappe/erpnext/pull/25882))
|
||||
- Create POS Invoice for Product Bundles ([#25847](https://github.com/frappe/erpnext/pull/25847))
|
||||
- Wrap dates in getdate for leave application ([#25899](https://github.com/frappe/erpnext/pull/25899))
|
||||
- Closing entry shows incorrect expected amount ([#25868](https://github.com/frappe/erpnext/pull/25868))
|
||||
- Add Hold status column in the Issue Summary Report ([#25828](https://github.com/frappe/erpnext/pull/25828))
|
||||
- Rendering of broken image on pos ([#25872](https://github.com/frappe/erpnext/pull/25872))
|
||||
- Timeout error in the repost item valuation ([#25854](https://github.com/frappe/erpnext/pull/25854))
|
||||
72
erpnext/change_log/v13/v13_6_0.md
Normal file
72
erpnext/change_log/v13/v13_6_0.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Version 13.6.0 Release Notes
|
||||
|
||||
### Features & Enhancements
|
||||
|
||||
- Job Card Enhancements ([#24523](https://github.com/frappe/erpnext/pull/24523))
|
||||
- Implement multi-account selection in General Ledger([#26044](https://github.com/frappe/erpnext/pull/26044))
|
||||
- Fetching of qty as per received qty from PR to PI ([#26184](https://github.com/frappe/erpnext/pull/26184))
|
||||
- Subcontract code refactor and enhancement ([#25878](https://github.com/frappe/erpnext/pull/25878))
|
||||
- Employee Grievance ([#25705](https://github.com/frappe/erpnext/pull/25705))
|
||||
- Add Inactive status to Employee ([#26030](https://github.com/frappe/erpnext/pull/26030))
|
||||
- Incorrect valuation rate report for serialized items ([#25696](https://github.com/frappe/erpnext/pull/25696))
|
||||
- Update cost updates operation time and hour rates in BOM ([#25891](https://github.com/frappe/erpnext/pull/25891))
|
||||
|
||||
### Fixes
|
||||
|
||||
- Precision rate for packed items in internal transfers ([#26046](https://github.com/frappe/erpnext/pull/26046))
|
||||
- User is not able to change item tax template ([#26176](https://github.com/frappe/erpnext/pull/26176))
|
||||
- Insufficient permission for Dunning error ([#26092](https://github.com/frappe/erpnext/pull/26092))
|
||||
- Validate Product Bundle for existing transactions before deletion ([#25978](https://github.com/frappe/erpnext/pull/25978))
|
||||
- Auto unlink warehouse from item on delete ([#26073](https://github.com/frappe/erpnext/pull/26073))
|
||||
- Employee Inactive status implications ([#26245](https://github.com/frappe/erpnext/pull/26245))
|
||||
- Fetch batch items in stock reconciliation ([#26230](https://github.com/frappe/erpnext/pull/26230))
|
||||
- Disabled cancellation for sales order if linked to drafted sales invoice ([#26125](https://github.com/frappe/erpnext/pull/26125))
|
||||
- Sort website products by weightage mentioned in Item master ([#26134](https://github.com/frappe/erpnext/pull/26134))
|
||||
- Added freeze when trying to stop work order (#26192) ([#26196](https://github.com/frappe/erpnext/pull/26196))
|
||||
- Accounting Dimensions for payroll entry accrual Journal Entry ([#26083](https://github.com/frappe/erpnext/pull/26083))
|
||||
- Staffing plan vacancies data type issue ([#25941](https://github.com/frappe/erpnext/pull/25941))
|
||||
- Unable to enter score in Assessment Result details grid ([#25945](https://github.com/frappe/erpnext/pull/25945))
|
||||
- Report Subcontracted Raw Materials to be Transferred ([#26011](https://github.com/frappe/erpnext/pull/26011))
|
||||
- Label for enabling ledger posting of change amount ([#26070](https://github.com/frappe/erpnext/pull/26070))
|
||||
- Training event ([#26071](https://github.com/frappe/erpnext/pull/26071))
|
||||
- Rate not able to change in purchase order ([#26122](https://github.com/frappe/erpnext/pull/26122))
|
||||
- Error while fetching item taxes ([#26220](https://github.com/frappe/erpnext/pull/26220))
|
||||
- Check for duplicate payment terms in Payment Term Template ([#26003](https://github.com/frappe/erpnext/pull/26003))
|
||||
- Removed values out of sync validation from stock transactions ([#26229](https://github.com/frappe/erpnext/pull/26229))
|
||||
- Fetching employee in payroll entry ([#26269](https://github.com/frappe/erpnext/pull/26269))
|
||||
- Filter Cost Center and Project drop-down lists by Company ([#26045](https://github.com/frappe/erpnext/pull/26045))
|
||||
- Website item group logic for product listing in Item Group pages ([#26170](https://github.com/frappe/erpnext/pull/26170))
|
||||
- Chart not visible for First Response Time reports ([#26032](https://github.com/frappe/erpnext/pull/26032))
|
||||
- Incorrect billed qty in Sales Order analytics ([#26095](https://github.com/frappe/erpnext/pull/26095))
|
||||
- Material request and supplier quotation not linked if supplier quotation created from supplier portal ([#26023](https://github.com/frappe/erpnext/pull/26023))
|
||||
- Update leave allocation after submit ([#26191](https://github.com/frappe/erpnext/pull/26191))
|
||||
- Taxes on Internal Transfer payment entry ([#26188](https://github.com/frappe/erpnext/pull/26188))
|
||||
- Precision rate for packed items (bp #26046) ([#26217](https://github.com/frappe/erpnext/pull/26217))
|
||||
- Fixed rounding off ordered percent to 100 in condition ([#26152](https://github.com/frappe/erpnext/pull/26152))
|
||||
- Sanctioned loan amount limit check ([#26108](https://github.com/frappe/erpnext/pull/26108))
|
||||
- Purchase receipt gl entries with same item code ([#26202](https://github.com/frappe/erpnext/pull/26202))
|
||||
- Taxable value for invoices with additional discount ([#25906](https://github.com/frappe/erpnext/pull/25906))
|
||||
- Correct South Africa VAT Rate (Updated) ([#25894](https://github.com/frappe/erpnext/pull/25894))
|
||||
- Remove response_by and resolution_by if sla is removed ([#25997](https://github.com/frappe/erpnext/pull/25997))
|
||||
- POS loyalty card alignment ([#26051](https://github.com/frappe/erpnext/pull/26051))
|
||||
- Flaky test for Report Subcontracted Raw materials to be transferred ([#26043](https://github.com/frappe/erpnext/pull/26043))
|
||||
- Export invoices not visible in GSTR-1 report ([#26143](https://github.com/frappe/erpnext/pull/26143))
|
||||
- Account filter not working with accounting dimension filter ([#26211](https://github.com/frappe/erpnext/pull/26211))
|
||||
- Allow to select group warehouse while downloading materials from production plan ([#26126](https://github.com/frappe/erpnext/pull/26126))
|
||||
- Added freeze when trying to stop work order ([#26192](https://github.com/frappe/erpnext/pull/26192))
|
||||
- Time out while submit / cancel the stock transactions with more than 50 Items ([#26081](https://github.com/frappe/erpnext/pull/26081))
|
||||
- Address Card issues in e-commerce ([#26187](https://github.com/frappe/erpnext/pull/26187))
|
||||
- Error while booking deferred revenue ([#26195](https://github.com/frappe/erpnext/pull/26195))
|
||||
- Eliminate repeat creation of HSN codes ([#25947](https://github.com/frappe/erpnext/pull/25947))
|
||||
- Opening invoices can alter profit and loss of a closed year ([#25951](https://github.com/frappe/erpnext/pull/25951))
|
||||
- Payroll entry employee detail issue ([#25968](https://github.com/frappe/erpnext/pull/25968))
|
||||
- Auto tax calculations in Payment Entry ([#26037](https://github.com/frappe/erpnext/pull/26037))
|
||||
- Use pos invoice item name as unique identifier ([#26198](https://github.com/frappe/erpnext/pull/26198))
|
||||
- Billing address not fetched in Purchase Invoice ([#26100](https://github.com/frappe/erpnext/pull/26100))
|
||||
- Timeout while cancelling stock reconciliation ([#26098](https://github.com/frappe/erpnext/pull/26098))
|
||||
- Status indicator for delivery notes ([#26062](https://github.com/frappe/erpnext/pull/26062))
|
||||
- Unable to enter score in Assessment Result details grid ([#26031](https://github.com/frappe/erpnext/pull/26031))
|
||||
- Too many writes while renaming company abbreviation ([#26203](https://github.com/frappe/erpnext/pull/26203))
|
||||
- Chart not visible for First Response Time reports ([#26185](https://github.com/frappe/erpnext/pull/26185))
|
||||
- Job applicant link issue ([#25934](https://github.com/frappe/erpnext/pull/25934))
|
||||
- Fetch preferred shipping address (bp #26132) ([#26201](https://github.com/frappe/erpnext/pull/26201))
|
||||
@@ -330,9 +330,15 @@ class SellingController(StockController):
|
||||
|
||||
# For internal transfers use incoming rate as the valuation rate
|
||||
if self.is_internal_transfer():
|
||||
rate = flt(d.incoming_rate * d.conversion_factor, d.precision('rate'))
|
||||
if d.rate != rate:
|
||||
d.rate = rate
|
||||
if d.doctype == "Packed Item":
|
||||
incoming_rate = flt(d.incoming_rate * d.conversion_factor, d.precision('incoming_rate'))
|
||||
if d.incoming_rate != incoming_rate:
|
||||
d.incoming_rate = incoming_rate
|
||||
else:
|
||||
rate = flt(d.incoming_rate * d.conversion_factor, d.precision('rate'))
|
||||
if d.rate != rate:
|
||||
d.rate = rate
|
||||
|
||||
d.discount_percentage = 0
|
||||
d.discount_amount = 0
|
||||
frappe.msgprint(_("Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer")
|
||||
|
||||
@@ -11,7 +11,7 @@ from frappe.utils import cint, cstr, flt, get_link_to_form, getdate
|
||||
|
||||
import erpnext
|
||||
from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries, process_gl_map
|
||||
from erpnext.accounts.utils import check_if_stock_and_account_balance_synced, get_fiscal_year
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
from erpnext.stock import get_warehouse_account_map
|
||||
from erpnext.stock.stock_ledger import get_valuation_rate
|
||||
@@ -497,9 +497,6 @@ class StockController(AccountsController):
|
||||
})
|
||||
if future_sle_exists(args):
|
||||
create_repost_item_valuation_entry(args)
|
||||
elif not is_reposting_pending():
|
||||
check_if_stock_and_account_balance_synced(self.posting_date,
|
||||
self.company, self.doctype, self.name)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_quality_inspections(doctype, docname, items):
|
||||
|
||||
@@ -11,5 +11,5 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) {
|
||||
return{
|
||||
query: "erpnext.controllers.queries.employee_query"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class Attendance(Document):
|
||||
validate_status(self.status, ["Present", "Absent", "On Leave", "Half Day", "Work From Home"])
|
||||
self.validate_attendance_date()
|
||||
self.validate_duplicate_record()
|
||||
self.validate_employee_status()
|
||||
self.check_leave_record()
|
||||
|
||||
def validate_attendance_date(self):
|
||||
@@ -38,6 +39,10 @@ class Attendance(Document):
|
||||
frappe.throw(_("Attendance for employee {0} is already marked for the date {1}").format(
|
||||
frappe.bold(self.employee), frappe.bold(self.attendance_date)))
|
||||
|
||||
def validate_employee_status(self):
|
||||
if frappe.db.get_value("Employee", self.employee, "status") == "Inactive":
|
||||
frappe.throw(_("Cannot mark attendance for an Inactive employee {0}").format(self.employee))
|
||||
|
||||
def check_leave_record(self):
|
||||
leave_record = frappe.db.sql("""
|
||||
select leave_type, half_day, half_day_date
|
||||
|
||||
@@ -21,6 +21,9 @@ frappe.listview_settings['Attendance'] = {
|
||||
label: __('For Employee'),
|
||||
fieldtype: 'Link',
|
||||
options: 'Employee',
|
||||
get_query: () => {
|
||||
return {query: "erpnext.controllers.queries.employee_query"}
|
||||
},
|
||||
reqd: 1,
|
||||
onchange: function() {
|
||||
dialog.set_df_property("unmarked_days", "hidden", 1);
|
||||
|
||||
@@ -325,8 +325,7 @@ frappe.ui.form.on("BOM", {
|
||||
freeze: true,
|
||||
args: {
|
||||
update_parent: true,
|
||||
from_child_bom:false,
|
||||
save: frm.doc.docstatus === 1 ? true : false
|
||||
from_child_bom:false
|
||||
},
|
||||
callback: function(r) {
|
||||
refresh_field("items");
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from typing import List
|
||||
from collections import deque
|
||||
import frappe, erpnext
|
||||
from frappe.utils import cint, cstr, flt, today
|
||||
from frappe import _
|
||||
@@ -16,14 +17,85 @@ from frappe.model.mapper import get_mapped_doc
|
||||
|
||||
import functools
|
||||
|
||||
from six import string_types
|
||||
|
||||
from operator import itemgetter
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
}
|
||||
|
||||
|
||||
class BOMTree:
|
||||
"""Full tree representation of a BOM"""
|
||||
|
||||
# specifying the attributes to save resources
|
||||
# ref: https://docs.python.org/3/reference/datamodel.html#slots
|
||||
__slots__ = ["name", "child_items", "is_bom", "item_code", "exploded_qty", "qty"]
|
||||
|
||||
def __init__(self, name: str, is_bom: bool = True, exploded_qty: float = 1.0, qty: float = 1) -> None:
|
||||
self.name = name # name of node, BOM number if is_bom else item_code
|
||||
self.child_items: List["BOMTree"] = [] # list of child items
|
||||
self.is_bom = is_bom # true if the node is a BOM and not a leaf item
|
||||
self.item_code: str = None # item_code associated with node
|
||||
self.qty = qty # required unit quantity to make one unit of parent item.
|
||||
self.exploded_qty = exploded_qty # total exploded qty required for making root of tree.
|
||||
if not self.is_bom:
|
||||
self.item_code = self.name
|
||||
else:
|
||||
self.__create_tree()
|
||||
|
||||
def __create_tree(self):
|
||||
bom = frappe.get_cached_doc("BOM", self.name)
|
||||
self.item_code = bom.item
|
||||
|
||||
for item in bom.get("items", []):
|
||||
qty = item.qty / bom.quantity # quantity per unit
|
||||
exploded_qty = self.exploded_qty * qty
|
||||
if item.bom_no:
|
||||
child = BOMTree(item.bom_no, exploded_qty=exploded_qty, qty=qty)
|
||||
self.child_items.append(child)
|
||||
else:
|
||||
self.child_items.append(
|
||||
BOMTree(item.item_code, is_bom=False, exploded_qty=exploded_qty, qty=qty)
|
||||
)
|
||||
|
||||
def level_order_traversal(self) -> List["BOMTree"]:
|
||||
"""Get level order traversal of tree.
|
||||
E.g. for following tree the traversal will return list of nodes in order from top to bottom.
|
||||
BOM:
|
||||
- SubAssy1
|
||||
- item1
|
||||
- item2
|
||||
- SubAssy2
|
||||
- item3
|
||||
- item4
|
||||
|
||||
returns = [SubAssy1, item1, item2, SubAssy2, item3, item4]
|
||||
"""
|
||||
traversal = []
|
||||
q = deque()
|
||||
q.append(self)
|
||||
|
||||
while q:
|
||||
node = q.popleft()
|
||||
|
||||
for child in node.child_items:
|
||||
traversal.append(child)
|
||||
q.append(child)
|
||||
|
||||
return traversal
|
||||
|
||||
def __str__(self) -> str:
|
||||
return (
|
||||
f"{self.item_code}{' - ' + self.name if self.is_bom else ''} qty(per unit): {self.qty}"
|
||||
f" exploded_qty: {self.exploded_qty}"
|
||||
)
|
||||
|
||||
def __repr__(self, level: int = 0) -> str:
|
||||
rep = "┃ " * (level - 1) + "┣━ " * (level > 0) + str(self) + "\n"
|
||||
for child in self.child_items:
|
||||
rep += child.__repr__(level=level + 1)
|
||||
return rep
|
||||
|
||||
class BOM(WebsiteGenerator):
|
||||
website = frappe._dict(
|
||||
# page_title_field = "item_name",
|
||||
@@ -152,7 +224,7 @@ class BOM(WebsiteGenerator):
|
||||
if not args:
|
||||
args = frappe.form_dict.get('args')
|
||||
|
||||
if isinstance(args, string_types):
|
||||
if isinstance(args, str):
|
||||
import json
|
||||
args = json.loads(args)
|
||||
|
||||
@@ -600,6 +672,11 @@ class BOM(WebsiteGenerator):
|
||||
if not d.batch_size or d.batch_size <= 0:
|
||||
d.batch_size = 1
|
||||
|
||||
def get_tree_representation(self) -> BOMTree:
|
||||
"""Get a complete tree representation preserving order of child items."""
|
||||
return BOMTree(self.name)
|
||||
|
||||
|
||||
def get_bom_item_rate(args, bom_doc):
|
||||
if bom_doc.rm_cost_as_per == 'Valuation Rate':
|
||||
rate = get_valuation_rate(args) * (args.get("conversion_factor") or 1)
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from collections import deque
|
||||
import unittest
|
||||
import frappe
|
||||
from frappe.utils import cstr, flt
|
||||
from frappe.test_runner import make_test_records
|
||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
||||
from erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool import update_cost
|
||||
from six import string_types
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
from erpnext.tests.test_subcontracting import set_backflush_based_on
|
||||
@@ -227,11 +226,88 @@ class TestBOM(unittest.TestCase):
|
||||
supplied_items = sorted([d.rm_item_code for d in po.supplied_items])
|
||||
self.assertEqual(bom_items, supplied_items)
|
||||
|
||||
def test_bom_tree_representation(self):
|
||||
bom_tree = {
|
||||
"Assembly": {
|
||||
"SubAssembly1": {"ChildPart1": {}, "ChildPart2": {},},
|
||||
"SubAssembly2": {"ChildPart3": {}},
|
||||
"SubAssembly3": {"SubSubAssy1": {"ChildPart4": {}}},
|
||||
"ChildPart5": {},
|
||||
"ChildPart6": {},
|
||||
"SubAssembly4": {"SubSubAssy2": {"ChildPart7": {}}},
|
||||
}
|
||||
}
|
||||
parent_bom = create_nested_bom(bom_tree, prefix="")
|
||||
created_tree = parent_bom.get_tree_representation()
|
||||
|
||||
reqd_order = level_order_traversal(bom_tree)[1:] # skip first item
|
||||
created_order = created_tree.level_order_traversal()
|
||||
|
||||
self.assertEqual(len(reqd_order), len(created_order))
|
||||
|
||||
for reqd_item, created_item in zip(reqd_order, created_order):
|
||||
self.assertEqual(reqd_item, created_item.item_code)
|
||||
|
||||
|
||||
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})
|
||||
|
||||
|
||||
|
||||
|
||||
def level_order_traversal(node):
|
||||
traversal = []
|
||||
q = deque()
|
||||
q.append(node)
|
||||
|
||||
while q:
|
||||
node = q.popleft()
|
||||
|
||||
for node_name, subtree in node.items():
|
||||
traversal.append(node_name)
|
||||
q.append(subtree)
|
||||
|
||||
return traversal
|
||||
|
||||
def create_nested_bom(tree, prefix="_Test bom "):
|
||||
""" Helper function to create a simple nested bom from tree describing item names. (along with required items)
|
||||
"""
|
||||
|
||||
def create_items(bom_tree):
|
||||
for item_code, subtree in bom_tree.items():
|
||||
bom_item_code = prefix + item_code
|
||||
if not frappe.db.exists("Item", bom_item_code):
|
||||
frappe.get_doc(doctype="Item", item_code=bom_item_code, item_group="_Test Item Group").insert()
|
||||
create_items(subtree)
|
||||
create_items(tree)
|
||||
|
||||
def dfs(tree, node):
|
||||
"""naive implementation for searching right subtree"""
|
||||
for node_name, subtree in tree.items():
|
||||
if node_name == node:
|
||||
return subtree
|
||||
else:
|
||||
result = dfs(subtree, node)
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
order_of_creating_bom = reversed(level_order_traversal(tree))
|
||||
|
||||
for item in order_of_creating_bom:
|
||||
child_items = dfs(tree, item)
|
||||
if child_items:
|
||||
bom_item_code = prefix + item
|
||||
bom = frappe.get_doc(doctype="BOM", item=bom_item_code)
|
||||
for child_item in child_items.keys():
|
||||
bom.append("items", {"item_code": prefix + child_item})
|
||||
bom.insert()
|
||||
bom.submit()
|
||||
|
||||
return bom # parent bom is last bom
|
||||
|
||||
|
||||
def reset_item_valuation_rate(item_code, warehouse_list=None, qty=None, rate=None):
|
||||
if warehouse_list and isinstance(warehouse_list, string_types):
|
||||
if warehouse_list and isinstance(warehouse_list, str):
|
||||
warehouse_list = [warehouse_list]
|
||||
|
||||
if not warehouse_list:
|
||||
|
||||
@@ -389,17 +389,12 @@ class TestWorkOrder(unittest.TestCase):
|
||||
ste.submit()
|
||||
stock_entries.append(ste)
|
||||
|
||||
job_cards = frappe.get_all('Job Card', filters = {'work_order': work_order.name})
|
||||
job_cards = frappe.get_all('Job Card', filters = {'work_order': work_order.name}, order_by='creation asc')
|
||||
self.assertEqual(len(job_cards), len(bom.operations))
|
||||
|
||||
for i, job_card in enumerate(job_cards):
|
||||
doc = frappe.get_doc("Job Card", job_card)
|
||||
doc.append("time_logs", {
|
||||
"from_time": add_to_date(None, i),
|
||||
"hours": 1,
|
||||
"to_time": add_to_date(None, i + 1),
|
||||
"completed_qty": doc.for_quantity
|
||||
})
|
||||
doc.time_logs[0].completed_qty = 1
|
||||
doc.submit()
|
||||
|
||||
ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 1))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import json
|
||||
import math
|
||||
@@ -30,9 +29,6 @@ class ItemHasVariantError(frappe.ValidationError): pass
|
||||
class SerialNoQtyError(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
form_grid_templates = {
|
||||
"operations": "templates/form_grid/work_order_grid.html"
|
||||
}
|
||||
|
||||
class WorkOrder(Document):
|
||||
def onload(self):
|
||||
@@ -472,46 +468,47 @@ class WorkOrder(Document):
|
||||
|
||||
def set_work_order_operations(self):
|
||||
"""Fetch operations from BOM and set in 'Work Order'"""
|
||||
self.set('operations', [])
|
||||
|
||||
def _get_operations(bom_no, qty=1):
|
||||
return frappe.db.sql(
|
||||
f"""select
|
||||
operation, description, workstation, idx,
|
||||
base_hour_rate as hour_rate, time_in_mins * {qty} as time_in_mins,
|
||||
"Pending" as status, parent as bom, batch_size, sequence_id
|
||||
from
|
||||
`tabBOM Operation`
|
||||
where
|
||||
parent = %s order by idx
|
||||
""", bom_no, as_dict=1)
|
||||
|
||||
|
||||
self.set('operations', [])
|
||||
if not self.bom_no:
|
||||
return
|
||||
|
||||
if self.use_multi_level_bom:
|
||||
bom_list = frappe.get_doc("BOM", self.bom_no).traverse_tree()
|
||||
operations = []
|
||||
if not self.use_multi_level_bom:
|
||||
bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
|
||||
operations.extend(_get_operations(self.bom_no, qty=1.0/bom_qty))
|
||||
else:
|
||||
bom_list = [self.bom_no]
|
||||
bom_tree = frappe.get_doc("BOM", self.bom_no).get_tree_representation()
|
||||
bom_traversal = list(reversed(bom_tree.level_order_traversal()))
|
||||
bom_traversal.append(bom_tree) # add operation on top level item last
|
||||
|
||||
for d in bom_traversal:
|
||||
if d.is_bom:
|
||||
operations.extend(_get_operations(d.name, qty=d.exploded_qty))
|
||||
|
||||
for correct_index, operation in enumerate(operations, start=1):
|
||||
operation.idx = correct_index
|
||||
|
||||
operations = frappe.db.sql("""
|
||||
select
|
||||
operation, description, workstation, idx,
|
||||
base_hour_rate as hour_rate, time_in_mins,
|
||||
"Pending" as status, parent as bom, batch_size, sequence_id
|
||||
from
|
||||
`tabBOM Operation`
|
||||
where
|
||||
parent in (%s) order by idx
|
||||
""" % ", ".join(["%s"]*len(bom_list)), tuple(bom_list), as_dict=1)
|
||||
|
||||
self.set('operations', operations)
|
||||
|
||||
if self.use_multi_level_bom and self.get('operations') and self.get('items'):
|
||||
raw_material_operations = [d.operation for d in self.get('items')]
|
||||
operations = [d.operation for d in self.get('operations')]
|
||||
|
||||
for operation in raw_material_operations:
|
||||
if operation not in operations:
|
||||
self.append('operations', {
|
||||
'operation': operation
|
||||
})
|
||||
|
||||
self.calculate_time()
|
||||
|
||||
def calculate_time(self):
|
||||
bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
|
||||
|
||||
for d in self.get("operations"):
|
||||
d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * (flt(self.qty) / flt(d.batch_size))
|
||||
d.time_in_mins = flt(d.time_in_mins) * (flt(self.qty) / flt(d.batch_size))
|
||||
|
||||
self.calculate_operating_cost()
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"actions": [],
|
||||
"creation": "2014-10-16 14:35:41.950175",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"details",
|
||||
@@ -49,6 +48,7 @@
|
||||
{
|
||||
"fieldname": "bom",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "BOM",
|
||||
"no_copy": 1,
|
||||
"options": "BOM",
|
||||
@@ -68,6 +68,7 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"columns": 1,
|
||||
"description": "Operation completed for how many finished goods?",
|
||||
"fieldname": "completed_qty",
|
||||
"fieldtype": "Float",
|
||||
@@ -77,6 +78,7 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"columns": 1,
|
||||
"default": "Pending",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
@@ -119,6 +121,7 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"columns": 1,
|
||||
"description": "in Minutes",
|
||||
"fieldname": "time_in_mins",
|
||||
"fieldtype": "Float",
|
||||
@@ -205,7 +208,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-01-12 14:48:31.061286",
|
||||
"modified": "2021-06-24 14:36:12.835543",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Work Order Operation",
|
||||
@@ -214,4 +217,4 @@
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,10 +135,26 @@ frappe.ui.form.on('Payroll Entry', {
|
||||
});
|
||||
|
||||
frm.set_query('employee', 'employees', () => {
|
||||
if (!frm.doc.company) {
|
||||
frappe.msgprint(__("Please set a Company"));
|
||||
return [];
|
||||
let error_fields = [];
|
||||
let mandatory_fields = ['company', 'payroll_frequency', 'start_date', 'end_date'];
|
||||
|
||||
let message = __('Mandatory fields required in {0}', [__(frm.doc.doctype)]);
|
||||
|
||||
mandatory_fields.forEach(field => {
|
||||
if (!frm.doc[field]) {
|
||||
error_fields.push(frappe.unscrub(field));
|
||||
}
|
||||
});
|
||||
|
||||
if (error_fields && error_fields.length) {
|
||||
message = message + '<br><br><ul><li>' + error_fields.join('</li><li>') + "</ul>";
|
||||
frappe.throw({
|
||||
message: message,
|
||||
indicator: 'red',
|
||||
title: __('Missing Fields')
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
query: "erpnext.payroll.doctype.payroll_entry.payroll_entry.employee_query",
|
||||
filters: frm.events.get_employee_filters(frm)
|
||||
@@ -148,25 +164,22 @@ frappe.ui.form.on('Payroll Entry', {
|
||||
|
||||
get_employee_filters: function (frm) {
|
||||
let filters = {};
|
||||
filters['company'] = frm.doc.company;
|
||||
filters['start_date'] = frm.doc.start_date;
|
||||
filters['end_date'] = frm.doc.end_date;
|
||||
filters['salary_slip_based_on_timesheet'] = frm.doc.salary_slip_based_on_timesheet;
|
||||
filters['payroll_frequency'] = frm.doc.payroll_frequency;
|
||||
filters['payroll_payable_account'] = frm.doc.payroll_payable_account;
|
||||
filters['currency'] = frm.doc.currency;
|
||||
|
||||
if (frm.doc.department) {
|
||||
filters['department'] = frm.doc.department;
|
||||
}
|
||||
if (frm.doc.branch) {
|
||||
filters['branch'] = frm.doc.branch;
|
||||
}
|
||||
if (frm.doc.designation) {
|
||||
filters['designation'] = frm.doc.designation;
|
||||
}
|
||||
let fields = ['company', 'start_date', 'end_date', 'payroll_frequency', 'payroll_payable_account',
|
||||
'currency', 'department', 'branch', 'designation'];
|
||||
|
||||
fields.forEach(field => {
|
||||
if (frm.doc[field]) {
|
||||
filters[field] = frm.doc[field];
|
||||
}
|
||||
});
|
||||
|
||||
if (frm.doc.employees) {
|
||||
filters['employees'] = frm.doc.employees.filter(d => d.employee).map(d => d.employee);
|
||||
let employees = frm.doc.employees.filter(d => d.employee).map(d => d.employee);
|
||||
if (employees && employees.length) {
|
||||
filters['employees'] = employees;
|
||||
}
|
||||
}
|
||||
return filters;
|
||||
},
|
||||
|
||||
@@ -459,6 +459,7 @@ def get_emp_list(sal_struct, cond, end_date, payroll_payable_account):
|
||||
where
|
||||
t1.name = t2.employee
|
||||
and t2.docstatus = 1
|
||||
and t1.status != 'Inactive'
|
||||
%s order by t2.from_date desc
|
||||
""" % cond, {"sal_struct": tuple(sal_struct), "from_date": end_date, "payroll_payable_account": payroll_payable_account}, as_dict=True)
|
||||
|
||||
@@ -679,6 +680,10 @@ def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
conditions = []
|
||||
include_employees = []
|
||||
emp_cond = ''
|
||||
|
||||
if not filters.payroll_frequency:
|
||||
frappe.throw(_('Select Payroll Frequency.'))
|
||||
|
||||
if filters.start_date and filters.end_date:
|
||||
employee_list = get_employee_list(filters)
|
||||
emp = filters.get('employees')
|
||||
|
||||
@@ -23,8 +23,8 @@ def search_by_term(search_term, warehouse, price_list):
|
||||
|
||||
item_stock_qty = get_stock_availability(item_code, warehouse)
|
||||
price_list_rate, currency = frappe.db.get_value('Item Price', {
|
||||
'price_list': price_list,
|
||||
'item_code': item_code
|
||||
'price_list': price_list,
|
||||
'item_code': item_code
|
||||
}, ["price_list_rate", "currency"]) or [None, None]
|
||||
|
||||
item_info.update({
|
||||
|
||||
@@ -428,7 +428,6 @@ def install_post_company_fixtures(args=None):
|
||||
frappe.local.flags.ignore_update_nsm = True
|
||||
make_records(records[1:])
|
||||
frappe.local.flags.ignore_update_nsm = False
|
||||
|
||||
rebuild_tree("Department", "parent_department")
|
||||
|
||||
|
||||
|
||||
@@ -48,37 +48,54 @@ frappe.ui.form.on("Stock Reconciliation", {
|
||||
},
|
||||
|
||||
get_items: function(frm) {
|
||||
frappe.prompt({label:"Warehouse", fieldname: "warehouse", fieldtype:"Link", options:"Warehouse", reqd: 1,
|
||||
let fields = [{
|
||||
label: 'Warehouse', fieldname: 'warehouse', fieldtype: 'Link', options: 'Warehouse', reqd: 1,
|
||||
"get_query": function() {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
}
|
||||
}
|
||||
}},
|
||||
function(data) {
|
||||
frappe.call({
|
||||
method:"erpnext.stock.doctype.stock_reconciliation.stock_reconciliation.get_items",
|
||||
args: {
|
||||
warehouse: data.warehouse,
|
||||
posting_date: frm.doc.posting_date,
|
||||
posting_time: frm.doc.posting_time,
|
||||
company:frm.doc.company
|
||||
},
|
||||
callback: function(r) {
|
||||
var items = [];
|
||||
frm.clear_table("items");
|
||||
for(var i=0; i< r.message.length; i++) {
|
||||
var d = frm.add_child("items");
|
||||
$.extend(d, r.message[i]);
|
||||
if(!d.qty) d.qty = null;
|
||||
if(!d.valuation_rate) d.valuation_rate = null;
|
||||
}
|
||||
frm.refresh_field("items");
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
, __("Get Items"), __("Update"));
|
||||
}, {
|
||||
label: "Item Code", fieldname: "item_code", fieldtype: "Link", options: "Item",
|
||||
"get_query": function() {
|
||||
return {
|
||||
"filters": {
|
||||
"disabled": 0,
|
||||
}
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
||||
frappe.prompt(fields, function(data) {
|
||||
frappe.call({
|
||||
method: "erpnext.stock.doctype.stock_reconciliation.stock_reconciliation.get_items",
|
||||
args: {
|
||||
warehouse: data.warehouse,
|
||||
posting_date: frm.doc.posting_date,
|
||||
posting_time: frm.doc.posting_time,
|
||||
company: frm.doc.company,
|
||||
item_code: data.item_code
|
||||
},
|
||||
callback: function(r) {
|
||||
frm.clear_table("items");
|
||||
for (var i=0; i<r.message.length; i++) {
|
||||
var d = frm.add_child("items");
|
||||
$.extend(d, r.message[i]);
|
||||
|
||||
if (!d.qty) {
|
||||
d.qty = 0;
|
||||
}
|
||||
|
||||
if (!d.valuation_rate) {
|
||||
d.valuation_rate = 0;
|
||||
}
|
||||
}
|
||||
frm.refresh_field("items");
|
||||
}
|
||||
});
|
||||
}, __("Get Items"), __("Update"));
|
||||
},
|
||||
|
||||
posting_date: function(frm) {
|
||||
|
||||
@@ -481,45 +481,99 @@ class StockReconciliation(StockController):
|
||||
self._cancel()
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_items(warehouse, posting_date, posting_time, company):
|
||||
def get_items(warehouse, posting_date, posting_time, company, item_code=None):
|
||||
items = [frappe._dict({
|
||||
'item_code': item_code,
|
||||
'warehouse': warehouse
|
||||
})]
|
||||
|
||||
if not item_code:
|
||||
items = get_items_for_stock_reco(warehouse, company)
|
||||
|
||||
res = []
|
||||
itemwise_batch_data = get_itemwise_batch(warehouse, posting_date, company, item_code)
|
||||
|
||||
for d in items:
|
||||
if d.item_code in itemwise_batch_data:
|
||||
stock_bal = get_stock_balance(d.item_code, d.warehouse,
|
||||
posting_date, posting_time, with_valuation_rate=True)
|
||||
|
||||
for row in itemwise_batch_data.get(d.item_code):
|
||||
args = get_item_data(row, row.qty, stock_bal[1])
|
||||
res.append(args)
|
||||
else:
|
||||
stock_bal = get_stock_balance(d.item_code, d.warehouse, posting_date, posting_time,
|
||||
with_valuation_rate=True , with_serial_no=cint(d.has_serial_no))
|
||||
|
||||
args = get_item_data(d, stock_bal[0], stock_bal[1],
|
||||
stock_bal[2] if cint(d.has_serial_no) else '')
|
||||
|
||||
res.append(args)
|
||||
|
||||
return res
|
||||
|
||||
def get_items_for_stock_reco(warehouse, company):
|
||||
lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
|
||||
items = frappe.db.sql("""
|
||||
select i.name, i.item_name, bin.warehouse, i.has_serial_no
|
||||
select i.name as item_code, i.item_name, bin.warehouse as warehouse, i.has_serial_no, i.has_batch_no
|
||||
from tabBin bin, tabItem i
|
||||
where i.name=bin.item_code and i.disabled=0 and i.is_stock_item = 1
|
||||
and i.has_variants = 0 and i.has_batch_no = 0
|
||||
and exists(select name from `tabWarehouse` where lft >= %s and rgt <= %s and name=bin.warehouse)
|
||||
""", (lft, rgt))
|
||||
where i.name=bin.item_code and IFNULL(i.disabled, 0) = 0 and i.is_stock_item = 1
|
||||
and i.has_variants = 0 and exists(
|
||||
select name from `tabWarehouse` where lft >= %s and rgt <= %s and name=bin.warehouse
|
||||
)
|
||||
""", (lft, rgt), as_dict=1)
|
||||
|
||||
items += frappe.db.sql("""
|
||||
select i.name, i.item_name, id.default_warehouse, i.has_serial_no
|
||||
select i.name as item_code, i.item_name, id.default_warehouse as warehouse, i.has_serial_no, i.has_batch_no
|
||||
from tabItem i, `tabItem Default` id
|
||||
where i.name = id.parent
|
||||
and exists(select name from `tabWarehouse` where lft >= %s and rgt <= %s and name=id.default_warehouse)
|
||||
and i.is_stock_item = 1 and i.has_batch_no = 0
|
||||
and i.has_variants = 0 and i.disabled = 0 and id.company=%s
|
||||
and i.is_stock_item = 1 and i.has_variants = 0 and IFNULL(i.disabled, 0) = 0 and id.company=%s
|
||||
group by i.name
|
||||
""", (lft, rgt, company))
|
||||
""", (lft, rgt, company), as_dict=1)
|
||||
|
||||
res = []
|
||||
for d in set(items):
|
||||
stock_bal = get_stock_balance(d[0], d[2], posting_date, posting_time,
|
||||
with_valuation_rate=True , with_serial_no=cint(d[3]))
|
||||
return items
|
||||
|
||||
if frappe.db.get_value("Item", d[0], "disabled") == 0:
|
||||
res.append({
|
||||
"item_code": d[0],
|
||||
"warehouse": d[2],
|
||||
"qty": stock_bal[0],
|
||||
"item_name": d[1],
|
||||
"valuation_rate": stock_bal[1],
|
||||
"current_qty": stock_bal[0],
|
||||
"current_valuation_rate": stock_bal[1],
|
||||
"current_serial_no": stock_bal[2] if cint(d[3]) else '',
|
||||
"serial_no": stock_bal[2] if cint(d[3]) else ''
|
||||
})
|
||||
def get_item_data(row, qty, valuation_rate, serial_no=None):
|
||||
return {
|
||||
'item_code': row.item_code,
|
||||
'warehouse': row.warehouse,
|
||||
'qty': qty,
|
||||
'item_name': row.item_name,
|
||||
'valuation_rate': valuation_rate,
|
||||
'current_qty': qty,
|
||||
'current_valuation_rate': valuation_rate,
|
||||
'current_serial_no': serial_no,
|
||||
'serial_no': serial_no,
|
||||
'batch_no': row.get('batch_no')
|
||||
}
|
||||
|
||||
return res
|
||||
def get_itemwise_batch(warehouse, posting_date, company, item_code=None):
|
||||
from erpnext.stock.report.batch_wise_balance_history.batch_wise_balance_history import execute
|
||||
itemwise_batch_data = {}
|
||||
|
||||
filters = frappe._dict({
|
||||
'warehouse': warehouse,
|
||||
'from_date': posting_date,
|
||||
'to_date': posting_date,
|
||||
'company': company
|
||||
})
|
||||
|
||||
if item_code:
|
||||
filters.item_code = item_code
|
||||
|
||||
columns, data = execute(filters)
|
||||
|
||||
for row in data:
|
||||
itemwise_batch_data.setdefault(row[0], []).append(frappe._dict({
|
||||
'item_code': row[0],
|
||||
'warehouse': warehouse,
|
||||
'qty': row[8],
|
||||
'item_name': row[1],
|
||||
'batch_no': row[4]
|
||||
}))
|
||||
|
||||
return itemwise_batch_data
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_stock_balance_for(item_code, warehouse,
|
||||
|
||||
@@ -438,6 +438,13 @@ def get_barcode_data(items_list):
|
||||
@frappe.whitelist()
|
||||
def get_item_tax_info(company, tax_category, item_codes, item_rates=None, item_tax_templates=None):
|
||||
out = {}
|
||||
|
||||
if item_tax_templates is None:
|
||||
item_tax_templates = {}
|
||||
|
||||
if item_rates is None:
|
||||
item_rates = {}
|
||||
|
||||
if isinstance(item_codes, (str,)):
|
||||
item_codes = json.loads(item_codes)
|
||||
|
||||
@@ -453,7 +460,7 @@ def get_item_tax_info(company, tax_category, item_codes, item_rates=None, item_t
|
||||
|
||||
out[item_code[1]] = {}
|
||||
item = frappe.get_cached_doc("Item", item_code[0])
|
||||
args = {"company": company, "tax_category": tax_category, "net_rate": item_rates[item_code[1]]}
|
||||
args = {"company": company, "tax_category": tax_category, "net_rate": item_rates.get(item_code[1])}
|
||||
|
||||
if item_tax_templates:
|
||||
args.update({"item_tax_template": item_tax_templates.get(item_code[1])})
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
frappe.query_reports["Incorrect Stock Value Report"] = {
|
||||
"filters": [
|
||||
{
|
||||
"label": __("Company"),
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
{
|
||||
"label": __("Account"),
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"options": "Account",
|
||||
get_query: function() {
|
||||
var company = frappe.query_report.get_filter_value('company');
|
||||
return {
|
||||
filters: {
|
||||
"account_type": "Stock",
|
||||
"company": company
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": __("From Date"),
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"columns": [],
|
||||
"creation": "2021-06-22 15:35:05.148177",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"filters": [],
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2021-06-22 15:35:05.148177",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Incorrect Stock Value Report",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"ref_doctype": "Stock Ledger Entry",
|
||||
"report_name": "Incorrect Stock Value Report",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Stock User"
|
||||
},
|
||||
{
|
||||
"role": "Accounts Manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import erpnext
|
||||
from frappe import _
|
||||
from six import iteritems
|
||||
from frappe.utils import add_days, today, getdate
|
||||
from erpnext.stock.utils import get_stock_value_on
|
||||
from erpnext.accounts.utils import get_stock_and_account_balance
|
||||
|
||||
def execute(filters=None):
|
||||
if not erpnext.is_perpetual_inventory_enabled(filters.company):
|
||||
frappe.throw(_("Perpetual inventory required for the company {0} to view this report.")
|
||||
.format(filters.company))
|
||||
|
||||
data = get_data(filters)
|
||||
columns = get_columns(filters)
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_unsync_date(filters):
|
||||
date = filters.from_date
|
||||
if not date:
|
||||
date = frappe.db.sql(""" SELECT min(posting_date) from `tabStock Ledger Entry`""")
|
||||
date = date[0][0]
|
||||
|
||||
if not date:
|
||||
return
|
||||
|
||||
while getdate(date) < getdate(today()):
|
||||
account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(posting_date=date,
|
||||
company=filters.company, account = filters.account)
|
||||
|
||||
if abs(account_bal - stock_bal) > 0.1:
|
||||
return date
|
||||
|
||||
date = add_days(date, 1)
|
||||
|
||||
def get_data(report_filters):
|
||||
from_date = get_unsync_date(report_filters)
|
||||
|
||||
if not from_date:
|
||||
return []
|
||||
|
||||
result = []
|
||||
|
||||
voucher_wise_dict = {}
|
||||
data = frappe.db.sql('''
|
||||
SELECT
|
||||
name, posting_date, posting_time, voucher_type, voucher_no,
|
||||
stock_value_difference, stock_value, warehouse, item_code
|
||||
FROM
|
||||
`tabStock Ledger Entry`
|
||||
WHERE
|
||||
posting_date
|
||||
= %s and company = %s
|
||||
and is_cancelled = 0
|
||||
ORDER BY timestamp(posting_date, posting_time) asc, creation asc
|
||||
''', (from_date, report_filters.company), as_dict=1)
|
||||
|
||||
for d in data:
|
||||
voucher_wise_dict.setdefault((d.item_code, d.warehouse), []).append(d)
|
||||
|
||||
closing_date = add_days(from_date, -1)
|
||||
for key, stock_data in iteritems(voucher_wise_dict):
|
||||
prev_stock_value = get_stock_value_on(posting_date = closing_date, item_code=key[0], warehouse =key[1])
|
||||
for data in stock_data:
|
||||
expected_stock_value = prev_stock_value + data.stock_value_difference
|
||||
if abs(data.stock_value - expected_stock_value) > 0.1:
|
||||
data.difference_value = abs(data.stock_value - expected_stock_value)
|
||||
data.expected_stock_value = expected_stock_value
|
||||
result.append(data)
|
||||
|
||||
return result
|
||||
|
||||
def get_columns(filters):
|
||||
return [
|
||||
{
|
||||
"label": _("Stock Ledger ID"),
|
||||
"fieldname": "name",
|
||||
"fieldtype": "Link",
|
||||
"options": "Stock Ledger Entry",
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
"label": _("Posting Date"),
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date"
|
||||
},
|
||||
{
|
||||
"label": _("Posting Time"),
|
||||
"fieldname": "posting_time",
|
||||
"fieldtype": "Time"
|
||||
},
|
||||
{
|
||||
"label": _("Voucher Type"),
|
||||
"fieldname": "voucher_type",
|
||||
"width": "110"
|
||||
},
|
||||
{
|
||||
"label": _("Voucher No"),
|
||||
"fieldname": "voucher_no",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"options": "voucher_type",
|
||||
"width": "110"
|
||||
},
|
||||
{
|
||||
"label": _("Item Code"),
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"options": "Item",
|
||||
"width": "110"
|
||||
},
|
||||
{
|
||||
"label": _("Warehouse"),
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"width": "110"
|
||||
},
|
||||
{
|
||||
"label": _("Expected Stock Value"),
|
||||
"fieldname": "expected_stock_value",
|
||||
"fieldtype": "Currency",
|
||||
"width": "150"
|
||||
},
|
||||
{
|
||||
"label": _("Stock Value"),
|
||||
"fieldname": "stock_value",
|
||||
"fieldtype": "Currency",
|
||||
"width": "120"
|
||||
},
|
||||
{
|
||||
"label": _("Difference Value"),
|
||||
"fieldname": "difference_value",
|
||||
"fieldtype": "Currency",
|
||||
"width": "150"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user