| 
| 
		 After Width: | Height: | Size: 140 KiB  | 
| 
		 After Width: | Height: | Size: 76 KiB  | 
| 
		 After Width: | Height: | Size: 70 KiB  | 
| 
		 After Width: | Height: | Size: 69 KiB  | 
| 
		 After Width: | Height: | Size: 88 KiB  | 
| 
		 After Width: | Height: | Size: 222 KiB  | 
| 
		 Before Width: | Height: | Size: 767 KiB  | 
| 
		 After Width: | Height: | Size: 90 KiB  | 
@ -0,0 +1,129 @@ | 
				
			|||||
 | 
					/** @odoo-module **/ | 
				
			||||
 | 
					import { registry } from "@web/core/registry"; | 
				
			||||
 | 
					import { useService } from "@web/core/utils/hooks"; | 
				
			||||
 | 
					import { View } from "@web/views/view"; | 
				
			||||
 | 
					import { kanbanView } from "@web/views/kanban/kanban_view"; | 
				
			||||
 | 
					import { KanbanController } from "@web/views/kanban/kanban_controller"; | 
				
			||||
 | 
					import { KanbanRenderer } from "@web/views/kanban/kanban_renderer"; | 
				
			||||
 | 
					import { KanbanRecord } from "@web/views/kanban/kanban_record"; | 
				
			||||
 | 
					const { useState } = owl; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class CustomKanbanController extends KanbanController { | 
				
			||||
 | 
					    async setup(){ | 
				
			||||
 | 
					        super.setup() | 
				
			||||
 | 
					        this.state = useState({ | 
				
			||||
 | 
					            selectedStLineId: null, | 
				
			||||
 | 
					            linesWidgetData: null, | 
				
			||||
 | 
					            moveLineData: null, | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        this.action = useService("action") | 
				
			||||
 | 
					        this.orm = useService("orm") | 
				
			||||
 | 
					        const o_bank_reconcile_status_buttons_aside_left = document.getElementsByClassName("o_bank_reconcile_status_buttons_aside_left") | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    async openRecord(record, mode) { | 
				
			||||
 | 
					        this.state.moveLineData = null; | 
				
			||||
 | 
					        this.state.viewID = await this.orm.call('res.config.settings', 'get_view_id', []) | 
				
			||||
 | 
					        await this.mountStLine(record.resId); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const statementRecord = document.querySelectorAll('.o_bank_reconcile_st_line_kanban_card'); | 
				
			||||
 | 
					        statementRecord.forEach(line => { | 
				
			||||
 | 
					            line.addEventListener('click', async (event) => { | 
				
			||||
 | 
					                // Remove 'div-added' class and its child divs from all elements
 | 
				
			||||
 | 
					                statementRecord.forEach(item => { | 
				
			||||
 | 
					                    item.classList.remove('div-added'); | 
				
			||||
 | 
					                    const childDiv = item.querySelector('.new-div'); | 
				
			||||
 | 
					                    if (childDiv) { | 
				
			||||
 | 
					                        item.removeChild(childDiv); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                // Add 'div-added' class and new div to the clicked record
 | 
				
			||||
 | 
					                if (!line.classList.contains('div-added')) { | 
				
			||||
 | 
					                    const newDiv = document.createElement('div'); | 
				
			||||
 | 
					                    newDiv.classList.add('new-div'); // Add a class to identify the new div
 | 
				
			||||
 | 
					                    line.classList.add('div-added'); | 
				
			||||
 | 
					                    line.appendChild(newDiv); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    async mountStLine(stLineId){ | 
				
			||||
 | 
					        const currentStLineId = this.state.selectedStLineId; | 
				
			||||
 | 
					        if (currentStLineId !== stLineId) { | 
				
			||||
 | 
					            this.state.selectedStLineId = stLineId; // Update selected ST Line ID
 | 
				
			||||
 | 
					            try { | 
				
			||||
 | 
					                const data = await this.orm.call("account.bank.statement.line", "get_statement_line", [stLineId]); | 
				
			||||
 | 
					                this.state.linesWidgetData = data; | 
				
			||||
 | 
					            } catch (error) { | 
				
			||||
 | 
					                console.error("Error fetching statement line data:", error); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            try { | 
				
			||||
 | 
					                const data = await this.orm.call('account.bank.statement.line', 'read', [[stLineId]], { fields: ['lines_widget_json'] }); | 
				
			||||
 | 
					                if (data && data.length > 0 && data[0].lines_widget_json) { | 
				
			||||
 | 
					                    const parsedData = JSON.parse(data[0].lines_widget_json); | 
				
			||||
 | 
					                    const moveIdMatch = parsedData.move_id.match(/\((\d+),\)/); | 
				
			||||
 | 
					                    parsedData.numeric_move_id = moveIdMatch ? parseInt(moveIdMatch[1]) : null; | 
				
			||||
 | 
					                    this.state.moveLineData = parsedData; | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    console.warn("No lines_widget_json found for selected statement line."); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } catch (error) { | 
				
			||||
 | 
					                console.error("Error reading statement line:", error); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    get prepareFormPropsBankReconcile(){ | 
				
			||||
 | 
					        if (!this.state.selectedStLineId) { | 
				
			||||
 | 
					            return null; // or some default props
 | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return { | 
				
			||||
 | 
					            type: "form", | 
				
			||||
 | 
					            viewId: this.state.viewID, | 
				
			||||
 | 
					            context: { | 
				
			||||
 | 
					                default_st_line_id: this.state.selectedStLineId, | 
				
			||||
 | 
					                default_lines_widget: this.state.linesWidgetData || null, | 
				
			||||
 | 
					                default_move_line: this.state.moveLineData || null, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            display: { controlPanel: false, noBreadcrumbs: true}, | 
				
			||||
 | 
					            mode: "edit", | 
				
			||||
 | 
					            resModel: "account.bank.statement.line", | 
				
			||||
 | 
					            resId: this.state.selectedStLineId, | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					CustomKanbanController.components = { | 
				
			||||
 | 
					    ...CustomKanbanController.components, View } | 
				
			||||
 | 
					CustomKanbanController.template = "base_accounting_kit.CustomKanbanView"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export class BankCustomKanbanRenderer extends KanbanRenderer { | 
				
			||||
 | 
					    setup(){ | 
				
			||||
 | 
					        super.setup(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					export class BankReconcileKanbanRecord extends KanbanRecord { | 
				
			||||
 | 
					    setup(){ | 
				
			||||
 | 
					        super.setup(); | 
				
			||||
 | 
					        this.state=useState({ | 
				
			||||
 | 
					            Statement_record:{} | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					BankReconcileKanbanRecord.template = "base_accounting_kit.BankReconcileKanbanRecord"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					BankCustomKanbanRenderer.components = { | 
				
			||||
 | 
					    ...KanbanRenderer.components, | 
				
			||||
 | 
					    KanbanRecord: BankReconcileKanbanRecord, | 
				
			||||
 | 
					} | 
				
			||||
 | 
					BankCustomKanbanRenderer.template = "base_accounting_kit.BankRecKanbanRenderer"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const customKanbanView = { | 
				
			||||
 | 
					    ...kanbanView, | 
				
			||||
 | 
					    Controller: CustomKanbanController, | 
				
			||||
 | 
					    Renderer: BankCustomKanbanRenderer, | 
				
			||||
 | 
					    searchMenuTypes: ["filter"], | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Register it to the views registry
 | 
				
			||||
 | 
					registry.category("views").add("custom_kanban", customKanbanView); | 
				
			||||
@ -0,0 +1,168 @@ | 
				
			|||||
 | 
					/** @odoo-module **/ | 
				
			||||
 | 
					import { registry } from '@web/core/registry'; | 
				
			||||
 | 
					import { ListController } from "@web/views/list/list_controller"; | 
				
			||||
 | 
					import { listView } from "@web/views/list/list_view"; | 
				
			||||
 | 
					import { useState, useRef } from "@odoo/owl"; | 
				
			||||
 | 
					import { useListener, useService} from "@web/core/utils/hooks"; | 
				
			||||
 | 
					export class AccountMoveLineListController extends ListController { | 
				
			||||
 | 
					     constructor() { | 
				
			||||
 | 
					        super(...arguments); | 
				
			||||
 | 
					        this.resIdList = []; | 
				
			||||
 | 
					     } | 
				
			||||
 | 
					     setup(){ | 
				
			||||
 | 
					         super.setup(); | 
				
			||||
 | 
					         this.state = useState({ selectedRecordId: null , | 
				
			||||
 | 
					                                 selectedRecordIds: [],}); | 
				
			||||
 | 
					         this.action = useService("action") | 
				
			||||
 | 
					         this.orm = useService("orm") | 
				
			||||
 | 
					     } | 
				
			||||
 | 
					     async openRecord(record) { | 
				
			||||
 | 
					        const kanban_row = this.__owl__.bdom.parentEl.ownerDocument.querySelector(`tr[data-id]`); | 
				
			||||
 | 
					        const data_id = parseInt(kanban_row.getAttribute('data-id')) | 
				
			||||
 | 
					        var data = await this.orm.call('account.bank.statement.line', | 
				
			||||
 | 
					            'update_match_row_data', | 
				
			||||
 | 
					            [record.resId]) | 
				
			||||
 | 
					        await this.orm.call('account.bank.statement.line', 'write', [[data_id], { lines_widget_json: JSON.stringify(data) }]); | 
				
			||||
 | 
					        const rowSelector = this.__owl__.bdom.parentEl.querySelector(`tr[data-id='${record.id}']`) | 
				
			||||
 | 
					         if (!record.clickCount) { | 
				
			||||
 | 
					            record.clickCount = true | 
				
			||||
 | 
					            rowSelector.style.backgroundColor = "#d1ecf1"; | 
				
			||||
 | 
					         } else { | 
				
			||||
 | 
					            // Set the default background color here
 | 
				
			||||
 | 
					            record.clickCount = false; | 
				
			||||
 | 
					            rowSelector.style.backgroundColor = "white"; | 
				
			||||
 | 
					         } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const currencySymbol = await this.orm.call('res.currency', 'read',[record.data.currency_id[0]]) | 
				
			||||
 | 
					        const mainKanbanDiv = this.__owl__.bdom.parentEl.ownerDocument.querySelector('#base_accounting_reconcile') | 
				
			||||
 | 
					        const existingRow = this.__owl__.bdom.parentEl.ownerDocument.querySelector(`tr[data-resId="${record.resId}"]`) | 
				
			||||
 | 
					        const stateLineRow = this.__owl__.bdom.parentEl.ownerDocument.querySelector('.statement_row') | 
				
			||||
 | 
					        if (stateLineRow){ | 
				
			||||
 | 
					            const dataIdValue = stateLineRow.getAttribute('data-id'); | 
				
			||||
 | 
					            if(dataIdValue == record.resId){ | 
				
			||||
 | 
					                mainKanbanDiv.removeChild(stateLineRow); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if (existingRow) { | 
				
			||||
 | 
					            mainKanbanDiv.removeChild(existingRow); | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            // If the row doesn't exist, create and add it
 | 
				
			||||
 | 
					            const dateObject = new Date(record.data.date); | 
				
			||||
 | 
					            const year = dateObject.getFullYear(); | 
				
			||||
 | 
					            const month = String(dateObject.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
 | 
				
			||||
 | 
					            const day = String(dateObject.getDate()).padStart(2, '0'); | 
				
			||||
 | 
					            const formattedDate = `${year}-${month}-${day}`; | 
				
			||||
 | 
					            let amount = parseFloat(record.data.amount_residual); | 
				
			||||
 | 
					            let debitColumn = ''; | 
				
			||||
 | 
					            let creditColumn = ''; | 
				
			||||
 | 
					            let partnerName = ''; | 
				
			||||
 | 
					            let moveId = ''; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            // Check if partner_id exists and is not empty
 | 
				
			||||
 | 
					            if (record.data.partner_id && record.data.partner_id[1]) { | 
				
			||||
 | 
					                partnerName = record.data.partner_id[1]; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if (record.data.move_id && record.data.move_id[1]) { | 
				
			||||
 | 
					                moveId = `<br/><span id="moveLine" style="font-size: 12px; font-style: italic;font-weight: normal;color: #01666b;cursor: pointer;" data-moveId="${record.data.move_id[0]}">${record.data.move_id[1]}</span>`; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            if (amount < 0) { | 
				
			||||
 | 
					                debitColumn = `<td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${currencySymbol[0].symbol} ${-amount}</td>`; | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                creditColumn = `<td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${currencySymbol[0].symbol} ${amount}</td>`; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            const newRow = document.createElement('tr'); | 
				
			||||
 | 
					            newRow.setAttribute('data-resId', record.resId); // Set a unique identifier for the row
 | 
				
			||||
 | 
					            if (debitColumn !== '') { | 
				
			||||
 | 
					                newRow.innerHTML = `<td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${record.data.account_id[1]} | 
				
			||||
 | 
					                                    ${moveId}<span style="font-size: 12px;font-style: italic;font-weight: normal;"> : ${record.data.name}</span></td> | 
				
			||||
 | 
					                                    <td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${partnerName}</td> | 
				
			||||
 | 
					                                    <td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${formattedDate}</td> | 
				
			||||
 | 
					                                    ${debitColumn} | 
				
			||||
 | 
					                                    <td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;"> </td> | 
				
			||||
 | 
					                                    <td class="o_list_remove_record"> | 
				
			||||
 | 
					                                    <button class="btn fa fa-trash-o" data-resId="${record.resId}"/> | 
				
			||||
 | 
					                                    </td>`; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            } else if (creditColumn !== '') { | 
				
			||||
 | 
					                newRow.innerHTML = `<td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${record.data.account_id[1]} | 
				
			||||
 | 
					                                    ${moveId}<span style="font-size: 12px;font-style: italic;font-weight: normal;"> : ${record.data.name}</span></td> | 
				
			||||
 | 
					                                    <td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${partnerName}</td> | 
				
			||||
 | 
					                                    <td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;">${formattedDate}</td> | 
				
			||||
 | 
					                                    <td style="font-weight: bold; display: table-cell; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top;"> </td> | 
				
			||||
 | 
					                                    ${creditColumn} | 
				
			||||
 | 
					                                    <td class="o_list_remove_record"> | 
				
			||||
 | 
					                                    <button class="btn fa fa-trash-o" data-resId="${record.resId}"/> | 
				
			||||
 | 
					                                    </td>`; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            newRow.addEventListener('click', async () => { | 
				
			||||
 | 
					                const allRows = this.__owl__.bdom.parentEl.ownerDocument.querySelectorAll('tr[data-resId]'); | 
				
			||||
 | 
					                allRows.forEach(row => { | 
				
			||||
 | 
					                    row.classList.remove('selected-row'); | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                 newRow.classList.add('selected-row'); | 
				
			||||
 | 
					                 if (record.resId){ | 
				
			||||
 | 
					                    const manualOpsTab = this.__owl__.bdom.parentEl.ownerDocument.querySelector('[name="manual_operations_tab"]'); | 
				
			||||
 | 
					                    if (manualOpsTab) { | 
				
			||||
 | 
					                        manualOpsTab.click(); | 
				
			||||
 | 
					                        const accountField = this.__owl__.bdom.parentEl.ownerDocument.querySelector('[name="account_id"]'); | 
				
			||||
 | 
					                        accountField.value = record.data.account_id[1]; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                 } | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            // Append the new row to the mainKanbanDiv
 | 
				
			||||
 | 
					            mainKanbanDiv.appendChild(newRow); | 
				
			||||
 | 
					            const deleteButtons = this.__owl__.bdom.parentEl.ownerDocument.querySelectorAll('.fa-trash-o'); | 
				
			||||
 | 
					            deleteButtons.forEach(button => { | 
				
			||||
 | 
					                button.addEventListener('click', async (event) => { | 
				
			||||
 | 
					                    const resId = event.target.getAttribute('data-resId'); | 
				
			||||
 | 
					                    await this.removeRecord(resId); | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            const moveLine = this.__owl__.bdom.parentEl.ownerDocument.querySelectorAll('#moveLine'); | 
				
			||||
 | 
					            moveLine.forEach(line => { | 
				
			||||
 | 
					                line.addEventListener('click',async (event) => { | 
				
			||||
 | 
					                    const moveId = event.target.getAttribute('data-moveId'); | 
				
			||||
 | 
					                    await this.ShowMoveForm(moveId); | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        this.updateResIdList(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    async removeRecord(resId){ | 
				
			||||
 | 
					        const mainKanbanDiv = this.__owl__.bdom.parentEl.ownerDocument.querySelector('#base_accounting_reconcile'); | 
				
			||||
 | 
					        const rowToRemove = this.__owl__.bdom.parentEl.ownerDocument.querySelector(`tr[data-resId="${resId}"]`); | 
				
			||||
 | 
					        if (rowToRemove) { | 
				
			||||
 | 
					            mainKanbanDiv.removeChild(rowToRemove); | 
				
			||||
 | 
					            this.updateResIdList(); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    async ShowMoveForm(moveId) { | 
				
			||||
 | 
					    // Convert moveId from string to integer
 | 
				
			||||
 | 
					        const moveIdInt = parseInt(moveId, 10); | 
				
			||||
 | 
					        // Check if the conversion is successful
 | 
				
			||||
 | 
					        if (!isNaN(moveIdInt)) { | 
				
			||||
 | 
					            this.action.doAction({ | 
				
			||||
 | 
					                type: 'ir.actions.act_window', | 
				
			||||
 | 
					                res_model: 'account.move', | 
				
			||||
 | 
					                res_id: moveIdInt, | 
				
			||||
 | 
					                views: [[false, "form"]], | 
				
			||||
 | 
					                target: 'current', | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    updateResIdList() { | 
				
			||||
 | 
					        // Get all resId values from the current rows and update the resIdList array
 | 
				
			||||
 | 
					        const rows = this.__owl__.bdom.parentEl.ownerDocument.querySelectorAll('tr[data-resId]'); | 
				
			||||
 | 
					        this.resIdList = Array.from(rows).map(row => parseInt(row.getAttribute('data-resId'), 10)); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					AccountMoveLineListController.template = 'base_accounting_kit.AccountMoveLineListController'; | 
				
			||||
 | 
					export const AccountMoveListView = { | 
				
			||||
 | 
					    ...listView, | 
				
			||||
 | 
					    Controller: AccountMoveLineListController, | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					registry.category('views').add('account_move_line_list_controller', AccountMoveListView); | 
				
			||||
@ -0,0 +1,79 @@ | 
				
			|||||
 | 
					/** @odoo-module **/ | 
				
			||||
 | 
					import { registry } from '@web/core/registry'; | 
				
			||||
 | 
					import { useService } from "@web/core/utils/hooks"; | 
				
			||||
 | 
					import { _t } from "@web/core/l10n/translation"; | 
				
			||||
 | 
					const { Component, useState, useExternalListener } = owl; | 
				
			||||
 | 
					export class BankReconcileFormLinesWidget extends Component { | 
				
			||||
 | 
					    setup(){ | 
				
			||||
 | 
					        super.setup(); | 
				
			||||
 | 
					        this.state = useState({statementLineResult: null, | 
				
			||||
 | 
					                                MoveLineResult:null}); | 
				
			||||
 | 
					        this.action = useService("action") | 
				
			||||
 | 
					        this.orm = useService("orm") | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    range(n){ | 
				
			||||
 | 
					        return[...Array(Math.max(n,0)).keys()]; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    get record(){ | 
				
			||||
 | 
					        return this.props.record; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    async mountStatementLine(ev){ | 
				
			||||
 | 
					        const manualOpsTab = document.querySelector('[name="manual_operations_tab"]'); | 
				
			||||
 | 
					        if (manualOpsTab) { | 
				
			||||
 | 
					           manualOpsTab.click(); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    async onclickLink(ev){ | 
				
			||||
 | 
					        const id = ev.currentTarget.dataset.id; | 
				
			||||
 | 
					        if (id) { | 
				
			||||
 | 
					            this.action.doAction({ | 
				
			||||
 | 
					                type: 'ir.actions.act_window', | 
				
			||||
 | 
					                res_model: 'account.move', | 
				
			||||
 | 
					                res_id: parseInt(id), | 
				
			||||
 | 
					                views: [[false, "form"]], | 
				
			||||
 | 
					                target: 'current', | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    async removeRecord(ev){ | 
				
			||||
 | 
					        ev.preventDefault(); | 
				
			||||
 | 
					        var button = ev.currentTarget; | 
				
			||||
 | 
					        var row = button.closest('tr'); | 
				
			||||
 | 
					        var firstRow = document.querySelector('.o_data_row:first-child'); | 
				
			||||
 | 
					        var data_id = firstRow.dataset.id; | 
				
			||||
 | 
					        try { | 
				
			||||
 | 
					            await this.orm.call('account.bank.statement.line', 'write', [[parseInt(data_id)], {'lines_widget_json': null}]); | 
				
			||||
 | 
					            // Update the UI or perform any other actions as needed
 | 
				
			||||
 | 
					        } catch (error) { | 
				
			||||
 | 
					            console.error('Error removing lines_widget_json:', error); | 
				
			||||
 | 
					            // Handle the error as needed
 | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        row.remove(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    getRenderValues(){ | 
				
			||||
 | 
					        var self=this; | 
				
			||||
 | 
					        let data = this.props.record.context | 
				
			||||
 | 
					        this.orm.call('account.bank.statement.line', 'update_rowdata', [this.props.record.data.id]) | 
				
			||||
 | 
					        let columns=[ | 
				
			||||
 | 
					            ["account",_t("Account")], | 
				
			||||
 | 
					            ["partner",_t("Partner")], | 
				
			||||
 | 
					            ["date",_t("Date")], | 
				
			||||
 | 
					        ]; | 
				
			||||
 | 
					        if(data.display_analytic_account_column){ | 
				
			||||
 | 
					            columns.push(["analytic_account", _t("Analytic Account")]); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if(data.display_multi_currency_column){ | 
				
			||||
 | 
					            columns.push(["amount_currency", _t("Amount in Currency")], ["currency", _t("Currency")]); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if(data.display_taxes_column){ | 
				
			||||
 | 
					            columns.push(["taxes", _t("Taxes")]); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        columns.push(["debit", _t("Debit")], ["credit", _t("Credit")], ["__trash", ""]); | 
				
			||||
 | 
					        return {...data,columns:columns} | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					BankReconcileFormLinesWidget.template = 'base_accounting_kit.bank_reconcile_widget_lines_widget'; | 
				
			||||
 | 
					export const FormLines = { | 
				
			||||
 | 
					    component: BankReconcileFormLinesWidget | 
				
			||||
 | 
					} | 
				
			||||
 | 
					registry.category("fields").add('bank_reconcile_widget_lines_widget', FormLines) | 
				
			||||
@ -0,0 +1,124 @@ | 
				
			|||||
 | 
					/** @odoo-module **/ | 
				
			||||
 | 
					import { registry } from '@web/core/registry'; | 
				
			||||
 | 
					import { standardWidgetProps } from "@web/views/widgets/standard_widget_props"; | 
				
			||||
 | 
					import { View } from "@web/views/view"; | 
				
			||||
 | 
					const { Component, useSubEnv } = owl; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class FormListView extends Component { | 
				
			||||
 | 
					    setup(){ | 
				
			||||
 | 
					        useSubEnv({ | 
				
			||||
 | 
					            config:{}, | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    get bankReconcileListViewProps(){ | 
				
			||||
 | 
					        return{ | 
				
			||||
 | 
					            type:'list', | 
				
			||||
 | 
					            display:{ | 
				
			||||
 | 
					                controlPanel:{ | 
				
			||||
 | 
					                    "top-left":false, | 
				
			||||
 | 
					                    "bottom-left":false, | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            resModel:this.props.resModel, | 
				
			||||
 | 
					            searchMenuTypes:["filter"], | 
				
			||||
 | 
					            allowSelectors:false, | 
				
			||||
 | 
					            searchViewId:false, | 
				
			||||
 | 
					            searchViewArch: ` | 
				
			||||
 | 
					                <search> | 
				
			||||
 | 
					                    <field name="name" string="Journal Item"/> | 
				
			||||
 | 
					                    <field name="journal_id"/> | 
				
			||||
 | 
					                    <field name="account_id"/> | 
				
			||||
 | 
					                    <field name="partner_id"/> | 
				
			||||
 | 
					                    <field name="move_id"/> | 
				
			||||
 | 
					                    <field name="currency_id" groups="base.group_multi_currency"/> | 
				
			||||
 | 
					                    <field name="date" string="Date"/> | 
				
			||||
 | 
					                    <separator/> | 
				
			||||
 | 
					                    <filter name="amount_received" string="Incoming" domain="[('balance','>',0.0)]"/> | 
				
			||||
 | 
					                    <filter name="amount_paid" string="Outgoing" domain="[('balance','<',0.0)]"/> | 
				
			||||
 | 
					                    <separator name="inject_after"/> | 
				
			||||
 | 
					                    <filter name="date" string="Date" date="date"/> | 
				
			||||
 | 
					                    <filter string="Customer/Vendor" name="partner_id" domain="[]"/> | 
				
			||||
 | 
					                    <filter string="Miscellaneous" domain="[('journal_id.type', '=', 'general')]" name="misc_filter"/> | 
				
			||||
 | 
					                </search> | 
				
			||||
 | 
					            `,
 | 
				
			||||
 | 
					            searchViewFields: { | 
				
			||||
 | 
					                name: { | 
				
			||||
 | 
					                    name:"name", | 
				
			||||
 | 
					                    string:"Journal Item", | 
				
			||||
 | 
					                    type:"char", | 
				
			||||
 | 
					                    store: true, | 
				
			||||
 | 
					                    sortable: true, | 
				
			||||
 | 
					                    searchable: true, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                date: { | 
				
			||||
 | 
					                    name: "date", | 
				
			||||
 | 
					                    string: "Date", | 
				
			||||
 | 
					                    type: "date", | 
				
			||||
 | 
					                    store: true, | 
				
			||||
 | 
					                    sortable: true, | 
				
			||||
 | 
					                    searchable: true, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                journal_id: { | 
				
			||||
 | 
					                    name: "journal_id", | 
				
			||||
 | 
					                    string: "Journal", | 
				
			||||
 | 
					                    type: "many2one", | 
				
			||||
 | 
					                    store: true, | 
				
			||||
 | 
					                    sortable: true, | 
				
			||||
 | 
					                    searchable: true, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                account_id: { | 
				
			||||
 | 
					                    name: "account_id", | 
				
			||||
 | 
					                    string: "Account", | 
				
			||||
 | 
					                    type: "many2one", | 
				
			||||
 | 
					                    store: true, | 
				
			||||
 | 
					                    sortable: true, | 
				
			||||
 | 
					                    searchable: true, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                partner_id: { | 
				
			||||
 | 
					                    name: "partner_id", | 
				
			||||
 | 
					                    string: "Partner", | 
				
			||||
 | 
					                    type: "many2one", | 
				
			||||
 | 
					                    store: true, | 
				
			||||
 | 
					                    sortable: true, | 
				
			||||
 | 
					                    searchable: true, | 
				
			||||
 | 
					                    group_by:"partner_id", | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                currency_id: { | 
				
			||||
 | 
					                    name: "currency_id", | 
				
			||||
 | 
					                    string: "Currency", | 
				
			||||
 | 
					                    type: "many2one", | 
				
			||||
 | 
					                    store: true, | 
				
			||||
 | 
					                    sortable: true, | 
				
			||||
 | 
					                    searchable: true, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                move_id: { | 
				
			||||
 | 
					                    name:"move_id", | 
				
			||||
 | 
					                    string:"Journal Entry", | 
				
			||||
 | 
					                    type:"many2one", | 
				
			||||
 | 
					                    store:true, | 
				
			||||
 | 
					                    sortable:true, | 
				
			||||
 | 
					                    searchable:true, | 
				
			||||
 | 
					                    filter_domain:"['|',('move_id.name','ilike',self),('move_id.ref','ilike',self)]", | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            context:{ | 
				
			||||
 | 
					                list_view_ref:"base_accounting_kit.account_move_line_view_tree", | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					FormListView.template = "base_accounting_kit.FormListView"; | 
				
			||||
 | 
					FormListView.components = { View }; | 
				
			||||
 | 
					FormListView.props = { | 
				
			||||
 | 
					    ...standardWidgetProps, | 
				
			||||
 | 
					    resModel: { type: String }, | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					export const formListView = { | 
				
			||||
 | 
					    component: FormListView, | 
				
			||||
 | 
					    extractProps: ({ attrs }) => ({ | 
				
			||||
 | 
					        resModel: attrs.resModel, | 
				
			||||
 | 
					    }), | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					registry.category("view_widgets").add("form_list_view", formListView); | 
				
			||||
@ -0,0 +1,33 @@ | 
				
			|||||
 | 
					<templates> | 
				
			||||
 | 
					    <t t-name="base_accounting_kit.CustomKanbanView" t-inherit="web.KanbanView" | 
				
			||||
 | 
					       owl="1"> | 
				
			||||
 | 
					        <xpath expr="//Layout" position="inside"> | 
				
			||||
 | 
					            <div class="h-100 form_view_class"> | 
				
			||||
 | 
					                <View t-if="state.selectedStLineId" | 
				
			||||
 | 
					                      t-props="prepareFormPropsBankReconcile" | 
				
			||||
 | 
					                      t-key="state.selectedStLineId"/> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </xpath> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    <t t-name="base_accounting_kit.BankRecKanbanRenderer" | 
				
			||||
 | 
					        t-inherit="web.KanbanRenderer" t-inherit-mode="primary" owl="1"> | 
				
			||||
 | 
					            <xpath expr="//div[hasclass('o_kanban_renderer')]" | 
				
			||||
 | 
					               position="before"> | 
				
			||||
 | 
					            </xpath> | 
				
			||||
 | 
					            <xpath expr="//div[hasclass('o_kanban_renderer')]" | 
				
			||||
 | 
					               position="attributes"> | 
				
			||||
 | 
					                <attribute name="class">o_kanban_renderer o_custom_class</attribute> | 
				
			||||
 | 
					            </xpath> | 
				
			||||
 | 
					            <xpath expr="//div[hasclass('o_custom_class')]" | 
				
			||||
 | 
					                   position="attributes"> | 
				
			||||
 | 
					                <attribute name="style">width:30%;</attribute> | 
				
			||||
 | 
					            </xpath> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    <t t-name="base_accounting_kit.BankReconcileKanbanRecord" | 
				
			||||
 | 
					       t-inherit="web.KanbanRecord" t-inherit-mode="primary" owl="1"> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    <t t-name="base_accounting_kit.AccountMoveLineListController" | 
				
			||||
 | 
					       t-inherit="web.ListView" | 
				
			||||
 | 
					       t-inherit-mode="primary" owl="1"> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					</templates> | 
				
			||||
@ -0,0 +1,124 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="utf-8" ?> | 
				
			||||
 | 
					<templates id="template" xml:space="preserve"> | 
				
			||||
 | 
					    <t t-name="base_accounting_kit.bank_reconcile_widget_lines_widget"> | 
				
			||||
 | 
					        <t t-set="data" t-value="getRenderValues()"/> | 
				
			||||
 | 
					        <div class="o_list_renderer table-responsive"> | 
				
			||||
 | 
					            <table class="table table-sm position-relative mb-0 o_list_table_ungrouped table-striped o_bank_reconcile_lines_widget_line"> | 
				
			||||
 | 
					                <thead> | 
				
			||||
 | 
					                    <tr> | 
				
			||||
 | 
					                        <t t-foreach="data.columns" t-as="column" | 
				
			||||
 | 
					                           t-key="column[0]"> | 
				
			||||
 | 
					                            <th t-esc="column[1]"/> | 
				
			||||
 | 
					                        </t> | 
				
			||||
 | 
					                    </tr> | 
				
			||||
 | 
					                </thead> | 
				
			||||
 | 
					                <tbody id="base_accounting_reconcile"> | 
				
			||||
 | 
					                    <t t-if="data.default_lines_widget"> | 
				
			||||
 | 
					                        <t t-foreach="data.default_lines_widget" t-as="line" | 
				
			||||
 | 
					                           t-key="line.id"> | 
				
			||||
 | 
					                            <tr class="o_data_row" | 
				
			||||
 | 
					                                t-on-click="mountStatementLine" | 
				
			||||
 | 
					                                t-att-data-id="line.id"> | 
				
			||||
 | 
					                                <t t-set="account" | 
				
			||||
 | 
					                                   t-value="line.account_code+' '+line.account_name"/> | 
				
			||||
 | 
					                                <t t-set="amount" | 
				
			||||
 | 
					                                   t-value="line.currency_symbol+' '+line.amount"/> | 
				
			||||
 | 
					                                <td class="o_data_cell o_field_cell" | 
				
			||||
 | 
					                                    style="font-weight: bolder;" | 
				
			||||
 | 
					                                    field="account_id"> | 
				
			||||
 | 
					                                    <t t-esc="account"/> | 
				
			||||
 | 
					                                    <br/> | 
				
			||||
 | 
					                                    <span class="text-muted" | 
				
			||||
 | 
					                                          style="font-style: italic;"> | 
				
			||||
 | 
					                                        <t t-esc="line.payment_ref"/> | 
				
			||||
 | 
					                                    </span> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <t t-if="line.partner_id"> | 
				
			||||
 | 
					                                    <td field="partner_id" | 
				
			||||
 | 
					                                        t-esc="line.partner_id[1]" | 
				
			||||
 | 
					                                        style="font-weight: bolder;"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                                <t t-else=""> | 
				
			||||
 | 
					                                    <td t-esc="line.partner_id[1]"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                                <td field="date" | 
				
			||||
 | 
					                                    t-esc="line.date" | 
				
			||||
 | 
					                                    style="font-weight: bolder;"/> | 
				
			||||
 | 
					                                <t t-if="line.amount > 0"> | 
				
			||||
 | 
					                                    <td field="debit" | 
				
			||||
 | 
					                                        t-esc="amount" | 
				
			||||
 | 
					                                        style="font-weight: bolder;"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                                <t t-else=""> | 
				
			||||
 | 
					                                    <td t-esc="' '"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                                <t t-if="line.amount < 0"> | 
				
			||||
 | 
					                                    <td field="credit" | 
				
			||||
 | 
					                                        t-esc="amount" | 
				
			||||
 | 
					                                        style="font-weight: bolder;"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </t> | 
				
			||||
 | 
					                    </t> | 
				
			||||
 | 
					                    <t t-if="data.default_move_line"> | 
				
			||||
 | 
					                        <tr class="o_data_row statement_row" | 
				
			||||
 | 
					                            t-on-click="mountStatementLine" | 
				
			||||
 | 
					                            t-att-data-id="data.default_move_line.id"> | 
				
			||||
 | 
					                                <t t-set="amount_residual" | 
				
			||||
 | 
					                                   t-value="data.default_move_line.currency_symbol+' '+data.default_move_line.amount_residual"/> | 
				
			||||
 | 
					                            <t t-set="move_account" | 
				
			||||
 | 
					                               t-value="data.default_move_line.account_code+' '+data.default_move_line.account_name"/> | 
				
			||||
 | 
					                            <td class="o_data_cell o_field_cell" | 
				
			||||
 | 
					                                style="font-weight: bolder;"> | 
				
			||||
 | 
					                                     <t t-esc="move_account"/> | 
				
			||||
 | 
					                                <br/> | 
				
			||||
 | 
					                                <span style="font-size: 12px; font-style: italic;font-weight: normal;color: #01666b;cursor: pointer;" | 
				
			||||
 | 
					                                      t-att-data-id="data.default_move_line.numeric_move_id" | 
				
			||||
 | 
					                                      t-on-click="onclickLink"> | 
				
			||||
 | 
					                                    <t t-esc="data.default_move_line.move_name"/> | 
				
			||||
 | 
					                                </span> | 
				
			||||
 | 
					                                : | 
				
			||||
 | 
					                                <span class="text-muted" | 
				
			||||
 | 
					                                      style="font-style: italic;"> | 
				
			||||
 | 
					                                    <t t-esc="data.default_move_line.name"/> | 
				
			||||
 | 
					                                </span> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                            <t t-if="data.default_move_line.partner_id"> | 
				
			||||
 | 
					                                <td t-esc="data.default_move_line.partner_name" | 
				
			||||
 | 
					                                    style="font-weight: bolder;"/> | 
				
			||||
 | 
					                            </t> | 
				
			||||
 | 
					                            <t t-else=""> | 
				
			||||
 | 
					                                <td t-esc="data.default_move_line.partner_name"/> | 
				
			||||
 | 
					                            </t> | 
				
			||||
 | 
					                            <td t-esc="data.default_move_line.date" | 
				
			||||
 | 
					                                style="font-weight: bolder;"/> | 
				
			||||
 | 
					                            <t t-if="data.default_move_line.amount_residual < 0"> | 
				
			||||
 | 
					                                <td t-esc="amount_residual" | 
				
			||||
 | 
					                                    style="font-weight: bolder;"/> | 
				
			||||
 | 
					                            </t> | 
				
			||||
 | 
					                            <t t-else=""> | 
				
			||||
 | 
					                                <td t-esc="' '"/> | 
				
			||||
 | 
					                            </t> | 
				
			||||
 | 
					                            <t t-if="data.default_move_line.amount_residual > 0"> | 
				
			||||
 | 
					                                 <td t-esc="amount_residual" | 
				
			||||
 | 
					                                     style="font-weight: bolder;"/> | 
				
			||||
 | 
					                            </t> | 
				
			||||
 | 
					                            <t t-if="this.props.record.data.bank_state!='reconciled'"> | 
				
			||||
 | 
					                                <td class="o_list_remove_record"> | 
				
			||||
 | 
					                                    <button class="btn fa fa-trash-o" | 
				
			||||
 | 
					                                            style="margin-top: -4px;" | 
				
			||||
 | 
					                                            t-on-click="removeRecord"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </t> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                     </t> | 
				
			||||
 | 
					                </tbody> | 
				
			||||
 | 
					            </table> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    <t t-name="base_accounting_kit.FormListView" owl="1"> | 
				
			||||
 | 
					        <t t-if="props.record.id"> | 
				
			||||
 | 
					            <View t-props="bankReconcileListViewProps"/> | 
				
			||||
 | 
					        </t> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					</templates> | 
				
			||||
@ -0,0 +1,64 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					############################################################################# | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    You can modify it under the terms of the GNU LESSER | 
				
			||||
 | 
					#    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    This program is distributed in the hope that it will be useful, | 
				
			||||
 | 
					#    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
				
			||||
 | 
					#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
				
			||||
 | 
					#    GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | 
				
			||||
 | 
					#    (LGPL v3) along with this program. | 
				
			||||
 | 
					#    If not, see <http://www.gnu.org/licenses/>. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					############################################################################# | 
				
			||||
 | 
					from odoo import api, fields, models, SUPERUSER_ID, _ | 
				
			||||
 | 
					from odoo.exceptions import UserError | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class AccountUpdateLockDate(models.TransientModel): | 
				
			||||
 | 
					    _name = 'account.lock.date' | 
				
			||||
 | 
					    _description = 'Lock date for accounting' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    company_id = fields.Many2one(comodel_name='res.company', string="Company", | 
				
			||||
 | 
					                                 required=True) | 
				
			||||
 | 
					    sale_lock_date = fields.Date(string="Sales Lock Date", help='Prevents creating and modifying invoices up to the date.') | 
				
			||||
 | 
					    purchase_lock_date = fields.Date(string="Purchase Lock date", help='Prevents creating and modifying bills up to the date.') | 
				
			||||
 | 
					    hard_lock_date = fields.Date(string="Lock Everyone", | 
				
			||||
 | 
					                                       help="No users, including Advisers, can edit accounts prior to and " | 
				
			||||
 | 
					                                            "inclusive of this date. Use it for fiscal year locking for " | 
				
			||||
 | 
					                                            "example.") | 
				
			||||
 | 
					    @api.model | 
				
			||||
 | 
					    def default_get(self, field_list): | 
				
			||||
 | 
					        res = super(AccountUpdateLockDate, self).default_get(field_list) | 
				
			||||
 | 
					        company = self.env.company | 
				
			||||
 | 
					        res.update({ | 
				
			||||
 | 
					            'company_id': company.id, | 
				
			||||
 | 
					            'sale_lock_date': company.sale_lock_date, | 
				
			||||
 | 
					            'purchase_lock_date': company.purchase_lock_date, | 
				
			||||
 | 
					            'hard_lock_date': company.hard_lock_date, | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					        return res | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _check_execute_allowed(self): | 
				
			||||
 | 
					        self.ensure_one() | 
				
			||||
 | 
					        has_adviser_group = self.env.user.has_group( | 
				
			||||
 | 
					            'account.group_account_manager') | 
				
			||||
 | 
					        if not (has_adviser_group or self.env.uid == SUPERUSER_ID): | 
				
			||||
 | 
					            raise UserError(_("You are not allowed to execute this action.")) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def execute(self): | 
				
			||||
 | 
					        self.ensure_one() | 
				
			||||
 | 
					        self._check_execute_allowed() | 
				
			||||
 | 
					        self.company_id.sudo().write({ | 
				
			||||
 | 
					            'sale_lock_date': self.sale_lock_date, | 
				
			||||
 | 
					            'purchase_lock_date': self.purchase_lock_date, | 
				
			||||
 | 
					            'hard_lock_date': self.hard_lock_date, | 
				
			||||
 | 
					        }) | 
				
			||||
@ -0,0 +1,46 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="UTF-8"?> | 
				
			||||
 | 
					<odoo> | 
				
			||||
 | 
					<!--Account Lock Date Form View--> | 
				
			||||
 | 
					    <record model="ir.ui.view" id="account_lock_date_view_form"> | 
				
			||||
 | 
					        <field name="name">account.lock.date.view.form</field> | 
				
			||||
 | 
					        <field name="model">account.lock.date</field> | 
				
			||||
 | 
					        <field name="arch" type="xml"> | 
				
			||||
 | 
					            <form> | 
				
			||||
 | 
					                <group> | 
				
			||||
 | 
					                    <field name="company_id" invisible="1"/> | 
				
			||||
 | 
					                    <label for="sale_lock_date"/> | 
				
			||||
 | 
					                    <div class="d-flex"> | 
				
			||||
 | 
					                        <field name="sale_lock_date" class="oe_inline"/><span class="text-muted"><i>to lock invoices</i></span> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                    <label for="purchase_lock_date"/> | 
				
			||||
 | 
					                    <div class="d-flex"> | 
				
			||||
 | 
					                        <field name="purchase_lock_date" class="oe_inline"/><span class="text-muted"><i>to lock bills</i></span> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                    <field name="hard_lock_date" class="oe_inline"/> | 
				
			||||
 | 
					                </group> | 
				
			||||
 | 
					                <footer> | 
				
			||||
 | 
					                    <button string="Update" name="execute" type="object" class="btn-primary"/> | 
				
			||||
 | 
					                    <button string="Cancel" class="btn-default" special="cancel"/> | 
				
			||||
 | 
					                </footer> | 
				
			||||
 | 
					            </form> | 
				
			||||
 | 
					        </field> | 
				
			||||
 | 
					    </record> | 
				
			||||
 | 
					<!--Action Account Lock Date--> | 
				
			||||
 | 
					    <record model="ir.actions.act_window" id="account_update_lock_date_act_window"> | 
				
			||||
 | 
					        <field name="name">Lock your Fiscal Period</field> | 
				
			||||
 | 
					        <field name="res_model">account.lock.date</field> | 
				
			||||
 | 
					        <field name="view_mode">form</field> | 
				
			||||
 | 
					        <field name="target">new</field> | 
				
			||||
 | 
					    </record> | 
				
			||||
 | 
					<!--Menu Lock Dates--> | 
				
			||||
 | 
					    <menuitem id="actions_menu" | 
				
			||||
 | 
					              name="Actions" | 
				
			||||
 | 
					              sequence="500" | 
				
			||||
 | 
					              parent="account.menu_finance_entries" | 
				
			||||
 | 
					              groups="account.group_account_manager"/> | 
				
			||||
 | 
					    <menuitem id="menu_lock_dates" | 
				
			||||
 | 
					              name="Lock Dates" | 
				
			||||
 | 
					              action="account_update_lock_date_act_window" | 
				
			||||
 | 
					              parent="base_accounting_kit.actions_menu" | 
				
			||||
 | 
					              groups="account.group_account_manager"/> | 
				
			||||
 | 
					</odoo> | 
				
			||||