Merge lp:~npg-team/openobject-addons/partner_address_validation__npg into lp:openobject-addons/extra-trunk

Proposed by Novapoint Group
Status: Rejected
Rejected by: Numérigraphe
Proposed branch: lp:~npg-team/openobject-addons/partner_address_validation__npg
Merge into: lp:openobject-addons/extra-trunk
Diff against target: 4982221 lines (has conflicts)
Conflict adding file .bzrignore.  Moved existing file to .bzrignore.moved.
Conflict: can't delete account_analytic_package because it is not empty.  Not deleting.
Conflict because account_analytic_package is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_analytic_package/__init__.py
Contents conflict in account_analytic_package/__terp__.py
Contents conflict in account_analytic_package/account_analytic_package.py
Conflict: can't delete account_analytic_progress because it is not empty.  Not deleting.
Conflict because account_analytic_progress is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_analytic_progress/__init__.py
Contents conflict in account_analytic_progress/__terp__.py
Conflict: can't delete account_base because it is not empty.  Not deleting.
Conflict because account_base is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_base/__init__.py
Contents conflict in account_base/__terp__.py
Contents conflict in account_base/partner.py
Conflict: can't delete account_base/wizard because it is not empty.  Not deleting.
Conflict because account_base/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_base/wizard/__init__.py
Contents conflict in account_base/wizard/account_setup.py
Conflict: can't delete account_bob_import because it is not empty.  Not deleting.
Conflict because account_bob_import is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_bob_import/__init__.py
Contents conflict in account_bob_import/__terp__.py
Contents conflict in account_bob_import/account_bob_import_config.xml
Contents conflict in account_bob_import/bob_import_step_1.py
Contents conflict in account_bob_import/bob_import_step_2.py
Conflict: can't delete account_budget_project because it is not empty.  Not deleting.
Conflict because account_budget_project is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_budget_project/__init__.py
Contents conflict in account_budget_project/__terp__.py
Contents conflict in account_budget_project/account_budget_project.py
Conflict: can't delete account_cash_discount because it is not empty.  Not deleting.
Conflict because account_cash_discount is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_cash_discount/__init__.py
Contents conflict in account_cash_discount/__terp__.py
Contents conflict in account_cash_discount/account_cash_discount.py
Conflict: can't delete account_invoice_analytic_required because it is not empty.  Not deleting.
Conflict because account_invoice_analytic_required is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_invoice_analytic_required/__init__.py
Contents conflict in account_invoice_analytic_required/__terp__.py
Contents conflict in account_invoice_analytic_required/account_invoice_analytic_required.py
Conflict: can't delete account_invoice_india because it is not empty.  Not deleting.
Conflict because account_invoice_india is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_invoice_india/__init__.py
Contents conflict in account_invoice_india/__terp__.py
Contents conflict in account_invoice_india/account_invoice.py
Conflict: can't delete account_invoice_india/report because it is not empty.  Not deleting.
Conflict because account_invoice_india/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_invoice_india/report/__init__.py
Contents conflict in account_invoice_india/report/account_journal.py
Contents conflict in account_invoice_india/report/aged_trial_balance.py
Contents conflict in account_invoice_india/report/general_ledger.py
Contents conflict in account_invoice_india/report/invoice.py
Contents conflict in account_invoice_india/report/partner_balance.py
Contents conflict in account_invoice_india/report/report_third_party_ledger.py
Conflict: can't delete account_invoice_india/wizard because it is not empty.  Not deleting.
Conflict because account_invoice_india/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_invoice_india/wizard/__init__.py
Contents conflict in account_invoice_india/wizard/account_chart_wizard.py
Contents conflict in account_invoice_india/wizard/account_create.py
Contents conflict in account_invoice_india/wizard/wizard_aged_trial_balance.py
Contents conflict in account_invoice_india/wizard/wizard_journal_ledger.py
Contents conflict in account_invoice_india/wizard/wizard_partner_balance_report.py
Contents conflict in account_invoice_india/wizard/wizard_third_party_ledger.py
Conflict: can't delete account_invoice_number because it is not empty.  Not deleting.
Conflict because account_invoice_number is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_invoice_number/__init__.py
Contents conflict in account_invoice_number/__terp__.py
Contents conflict in account_invoice_number/account_invoice_number.py
Conflict: can't delete account_invoice_payment_term because it is not empty.  Not deleting.
Conflict because account_invoice_payment_term is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_invoice_payment_term/__init__.py
Contents conflict in account_invoice_payment_term/__terp__.py
Conflict: can't delete account_invoice_payment_term/report because it is not empty.  Not deleting.
Conflict because account_invoice_payment_term/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_invoice_payment_term/report/__init__.py
Contents conflict in account_invoice_payment_term/report/invoice.py
Conflict: can't delete account_journal_visibility because it is not empty.  Not deleting.
Conflict because account_journal_visibility is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_journal_visibility/__init__.py
Contents conflict in account_journal_visibility/__terp__.py
Contents conflict in account_journal_visibility/account_journal.py
Conflict: can't delete account_l10nbe_domiciliation because it is not empty.  Not deleting.
Conflict because account_l10nbe_domiciliation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_l10nbe_domiciliation/__init__.py
Contents conflict in account_l10nbe_domiciliation/__terp__.py
Contents conflict in account_l10nbe_domiciliation/l10nbe_domiciliation.py
Contents conflict in account_l10nbe_domiciliation/l10nbe_domiciliation_view.xml
Conflict: can't delete account_payment_export because it is not empty.  Not deleting.
Conflict because account_payment_export is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_payment_export/__init__.py
Contents conflict in account_payment_export/__terp__.py
Contents conflict in account_payment_export/payment_export.py
Conflict: can't delete account_payment_export/wizard because it is not empty.  Not deleting.
Conflict because account_payment_export/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_payment_export/wizard/__init__.py
Contents conflict in account_payment_export/wizard/export_wizard.py
Conflict: can't delete account_payment_extension because it is not empty.  Not deleting.
Conflict because account_payment_extension is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_payment_extension/account_invoice.py
Contents conflict in account_payment_extension/account_move_line.py
Conflict: can't delete account_payment_extension/i18n because it is not empty.  Not deleting.
Conflict because account_payment_extension/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_payment_extension/i18n/account_payment_extension.pot
Contents conflict in account_payment_extension/payment.py
Contents conflict in account_payment_extension/payment_view.xml
Conflict: can't delete account_payment_extension/security because it is not empty.  Not deleting.
Conflict because account_payment_extension/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_payment_extension/security/ir.model.access.csv
Conflict: can't delete account_payment_extension/wizard because it is not empty.  Not deleting.
Conflict because account_payment_extension/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_payment_extension/wizard/wizard_payment_order.py
Contents conflict in account_payment_extension/wizard/wizard_populate_statement.py
Conflict: can't delete account_regularization because it is not empty.  Not deleting.
Conflict because account_regularization is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_regularization/__terp__.py
Contents conflict in account_regularization/account.py
Conflict: can't delete account_regularization/i18n because it is not empty.  Not deleting.
Conflict because account_regularization/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete account_regularization/wizard because it is not empty.  Not deleting.
Conflict because account_regularization/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_regularization/wizard/account_regularization.py
Conflict: can't delete account_reports_india because it is not empty.  Not deleting.
Conflict because account_reports_india is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_reports_india/__init__.py
Contents conflict in account_reports_india/__terp__.py
Conflict: can't delete account_reports_india/report because it is not empty.  Not deleting.
Conflict because account_reports_india/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_reports_india/report/__init__.py
Contents conflict in account_reports_india/report/report_balance_sheet.py
Contents conflict in account_reports_india/report/report_balance_sheet_horizontal.py
Contents conflict in account_reports_india/report/report_pl_account.py
Contents conflict in account_reports_india/report/report_pl_horizontal.py
Contents conflict in account_reports_india/report/report_trial_balance.py
Contents conflict in account_reports_india/report/rml_parse.py
Conflict: can't delete account_reports_india/wizard because it is not empty.  Not deleting.
Conflict because account_reports_india/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_reports_india/wizard/__init__.py
Contents conflict in account_reports_india/wizard/wizard_balance_sheet.py
Contents conflict in account_reports_india/wizard/wizard_pl_report.py
Contents conflict in account_reports_india/wizard/wizard_trial_balance_sheet.py
Conflict: can't delete account_reverse because it is not empty.  Not deleting.
Conflict because account_reverse is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_reverse/__terp__.py
Contents conflict in account_reverse/account.py
Conflict: can't delete account_reverse/i18n because it is not empty.  Not deleting.
Conflict because account_reverse/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete account_reverse/wizard because it is not empty.  Not deleting.
Conflict because account_reverse/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_reverse/wizard/__init__.py
Contents conflict in account_reverse/wizard/account_move_reverse.py
Conflict: can't delete account_simulation because it is not empty.  Not deleting.
Conflict because account_simulation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_simulation/__init__.py
Contents conflict in account_simulation/__terp__.py
Contents conflict in account_simulation/account_simulation.py
Conflict: can't delete account_simulation/wizard because it is not empty.  Not deleting.
Conflict because account_simulation/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in account_simulation/wizard/__init__.py
Contents conflict in account_simulation/wizard/wizard_account_chart.py
Conflict: can't delete actions_server_mako_email because it is not empty.  Not deleting.
Conflict because actions_server_mako_email is not versioned, but has versioned children.  Versioned directory.
Contents conflict in actions_server_mako_email/__init__.py
Contents conflict in actions_server_mako_email/__terp__.py
Contents conflict in actions_server_mako_email/asme.py
Conflict: can't delete airport because it is not empty.  Not deleting.
Conflict because airport is not versioned, but has versioned children.  Versioned directory.
Contents conflict in airport/__init__.py
Contents conflict in airport/__terp__.py
Contents conflict in airport/custom.py
Conflict: can't delete analytic_partners because it is not empty.  Not deleting.
Conflict because analytic_partners is not versioned, but has versioned children.  Versioned directory.
Contents conflict in analytic_partners/__init__.py
Contents conflict in analytic_partners/__terp__.py
Contents conflict in analytic_partners/analytic_partners.py
Conflict: can't delete analytic_partners/report because it is not empty.  Not deleting.
Conflict because analytic_partners/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in analytic_partners/report/__init__.py
Contents conflict in analytic_partners/report/analytic_partners_report.py
Conflict: can't delete asterisk because it is not empty.  Not deleting.
Conflict because asterisk is not versioned, but has versioned children.  Versioned directory.
Contents conflict in asterisk/__init__.py
Contents conflict in asterisk/__terp__.py
Contents conflict in asterisk/asterisk.py
Conflict: can't delete asterisk/script because it is not empty.  Not deleting.
Conflict because asterisk/script is not versioned, but has versioned children.  Versioned directory.
Contents conflict in asterisk/script/rpc.py
Contents conflict in asterisk/script/simple_write.py
Contents conflict in asterisk/script/tiny_socket.py
Conflict: can't delete asterisk/wizard because it is not empty.  Not deleting.
Conflict because asterisk/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in asterisk/wizard/__init__.py
Contents conflict in asterisk/wizard/partner_get.py
Conflict: can't delete base_contact_city because it is not empty.  Not deleting.
Conflict because base_contact_city is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete base_contact_team because it is not empty.  Not deleting.
Conflict because base_contact_team is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_contact_team/__init__.py
Contents conflict in base_contact_team/__terp__.py
Contents conflict in base_contact_team/base_contact_team.py
Conflict: can't delete base_create_menu because it is not empty.  Not deleting.
Conflict because base_create_menu is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_create_menu/__init__.py
Contents conflict in base_create_menu/__terp__.py
Conflict: can't delete base_create_menu/i18n because it is not empty.  Not deleting.
Conflict because base_create_menu/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete base_create_menu/wizard because it is not empty.  Not deleting.
Conflict because base_create_menu/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_create_menu/wizard/__init__.py
Contents conflict in base_create_menu/wizard/menu_wizard.py
Conflict adding files to base_crypt.  Created directory.
Conflict because base_crypt is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_crypt/__init__.py
Contents conflict in base_crypt/__openerp__.py
Contents conflict in base_crypt/crypt.py
Conflict: can't delete base_language because it is not empty.  Not deleting.
Conflict because base_language is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_language/__init__.py
Contents conflict in base_language/__terp__.py
Contents conflict in base_language/base_language.py
Contents conflict in base_language/base_language_data.xml
Conflict: can't delete base_module_merge because it is not empty.  Not deleting.
Conflict because base_module_merge is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_module_merge/__init__.py
Contents conflict in base_module_merge/__terp__.py
Conflict: can't delete base_module_merge/wizard because it is not empty.  Not deleting.
Conflict because base_module_merge/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_module_merge/wizard/__init__.py
Contents conflict in base_module_merge/wizard/base_module_merge.py
Conflict: can't delete base_partner_gender because it is not empty.  Not deleting.
Conflict because base_partner_gender is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_partner_gender/__init__.py
Contents conflict in base_partner_gender/__terp__.py
Contents conflict in base_partner_gender/base_partner_gender.py
Conflict: can't delete base_partner_relation because it is not empty.  Not deleting.
Conflict because base_partner_relation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_partner_relation/__init__.py
Contents conflict in base_partner_relation/__terp__.py
Contents conflict in base_partner_relation/partner_relation.py
Conflict: can't delete base_partner_sequence because it is not empty.  Not deleting.
Conflict because base_partner_sequence is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_partner_sequence/__init__.py
Contents conflict in base_partner_sequence/__terp__.py
Contents conflict in base_partner_sequence/partner_sequence.py
Conflict: can't delete base_partner_surname because it is not empty.  Not deleting.
Conflict because base_partner_surname is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_partner_surname/__init__.py
Contents conflict in base_partner_surname/__terp__.py
Contents conflict in base_partner_surname/partner.py
Contents conflict in base_partner_surname/partner_view.xml
Conflict: can't delete base_report_model because it is not empty.  Not deleting.
Conflict because base_report_model is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_report_model/__init__.py
Contents conflict in base_report_model/__terp__.py
Contents conflict in base_report_model/base_report_model.py
Conflict: can't delete base_translation because it is not empty.  Not deleting.
Conflict because base_translation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_translation/__init__.py
Contents conflict in base_translation/__terp__.py
Conflict: can't delete base_translation/scripts because it is not empty.  Not deleting.
Conflict because base_translation/scripts is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_translation/scripts/config.py
Contents conflict in base_translation/scripts/translation_server.py
Contents conflict in base_translation/translation.py
Conflict: can't delete base_translation/wizard because it is not empty.  Not deleting.
Conflict because base_translation/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_translation/wizard/__init__.py
Contents conflict in base_translation/wizard/config.py
Contents conflict in base_translation/wizard/wizard_download_file_for_contrib.py
Contents conflict in base_translation/wizard/wizard_download_file_for_publish.py
Contents conflict in base_translation/wizard/wizard_publish_new_version.py
Contents conflict in base_translation/wizard/wizard_review_proposed_contributions.py
Contents conflict in base_translation/wizard/wizard_upload_contribution.py
Conflict: can't delete base_url_menu because it is not empty.  Not deleting.
Conflict because base_url_menu is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_url_menu/__init__.py
Contents conflict in base_url_menu/__terp__.py
Contents conflict in base_url_menu/base_url_menu.py
Conflict: can't delete base_url_menu/wizard because it is not empty.  Not deleting.
Conflict because base_url_menu/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_url_menu/wizard/__init__.py
Contents conflict in base_url_menu/wizard/base_url_menu_wizard.py
Conflict: can't delete base_vat_unique because it is not empty.  Not deleting.
Conflict because base_vat_unique is not versioned, but has versioned children.  Versioned directory.
Contents conflict in base_vat_unique/__init__.py
Contents conflict in base_vat_unique/__terp__.py
Contents conflict in base_vat_unique/base_vat_unique.py
Conflict: can't delete base_vat_unique/i18n because it is not empty.  Not deleting.
Conflict because base_vat_unique/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete board_dm because it is not empty.  Not deleting.
Conflict because board_dm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in board_dm/__init__.py
Contents conflict in board_dm/__terp__.py
Conflict: can't delete board_frontdesk because it is not empty.  Not deleting.
Conflict because board_frontdesk is not versioned, but has versioned children.  Versioned directory.
Contents conflict in board_frontdesk/__init__.py
Contents conflict in board_frontdesk/__terp__.py
Conflict: can't delete board_project_portal because it is not empty.  Not deleting.
Conflict because board_project_portal is not versioned, but has versioned children.  Versioned directory.
Contents conflict in board_project_portal/__init__.py
Contents conflict in board_project_portal/__terp__.py
Contents conflict in board_project_portal/board_project_portal.py
Contents conflict in board_project_portal/bug_form.xml
Conflict: can't delete board_reservation because it is not empty.  Not deleting.
Conflict because board_reservation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in board_reservation/__init__.py
Contents conflict in board_reservation/__terp__.py
Conflict: can't delete board_restaurant because it is not empty.  Not deleting.
Conflict because board_restaurant is not versioned, but has versioned children.  Versioned directory.
Contents conflict in board_restaurant/__init__.py
Contents conflict in board_restaurant/__terp__.py
Conflict: can't delete board_service because it is not empty.  Not deleting.
Conflict because board_service is not versioned, but has versioned children.  Versioned directory.
Contents conflict in board_service/__init__.py
Contents conflict in board_service/__terp__.py
Contents conflict in board_service/board_service_view.xml
Conflict: can't delete bookstore because it is not empty.  Not deleting.
Conflict because bookstore is not versioned, but has versioned children.  Versioned directory.
Contents conflict in bookstore/__init__.py
Contents conflict in bookstore/__terp__.py
Contents conflict in bookstore/account.py
Contents conflict in bookstore/book_data.xml
Contents conflict in bookstore/bookstore.py
Conflict: can't delete bookstore/i18n because it is not empty.  Not deleting.
Conflict because bookstore/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in bookstore/invoice.py
Contents conflict in bookstore/partner.py
Conflict: can't delete bookstore/report because it is not empty.  Not deleting.
Conflict because bookstore/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in bookstore/report/__init__.py
Contents conflict in bookstore/report/invoice.py
Contents conflict in bookstore/report/purchase_order.py
Contents conflict in bookstore/report/quotation.py
Contents conflict in bookstore/report/sales_order.py
Contents conflict in bookstore/report_intrastat.py
Contents conflict in bookstore/sale.py
Conflict: can't delete c2c_analytic_wizard because it is not empty.  Not deleting.
Conflict because c2c_analytic_wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_analytic_wizard/__init__.py
Contents conflict in c2c_analytic_wizard/__terp__.py
Conflict: can't delete c2c_analytic_wizard/i18n because it is not empty.  Not deleting.
Conflict because c2c_analytic_wizard/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_analytic_wizard/indicator_account_detail.py
Conflict: can't delete c2c_analytic_wizard/report because it is not empty.  Not deleting.
Conflict because c2c_analytic_wizard/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_analytic_wizard/report/__init__.py
Contents conflict in c2c_analytic_wizard/report/c2c_helper.py
Contents conflict in c2c_analytic_wizard/report/indicator_account_detail.py
Conflict: can't delete c2c_analytic_wizard/wizard because it is not empty.  Not deleting.
Conflict because c2c_analytic_wizard/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_analytic_wizard/wizard/__init__.py
Contents conflict in c2c_analytic_wizard/wizard/associate_analytic_line_from.py
Contents conflict in c2c_analytic_wizard/wizard/associate_analytic_line_toinvoice.py
Contents conflict in c2c_analytic_wizard/wizard/blank_invoice.py
Contents conflict in c2c_analytic_wizard/wizard/dissociate_aal_from_invoice.py
Contents conflict in c2c_analytic_wizard/wizard/indicator_account_detail.py
Contents conflict in c2c_analytic_wizard/wizard/invoice_create.py
Contents conflict in c2c_analytic_wizard/wizard/open_specified_analytic_line.py
Contents conflict in c2c_analytic_wizard/wizard/open_specified_invoices.py
Conflict: can't delete c2c_budget because it is not empty.  Not deleting.
Conflict because c2c_budget is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_budget/__init__.py
Contents conflict in c2c_budget/__terp__.py
Contents conflict in c2c_budget/account.py
Contents conflict in c2c_budget/analytic_account.py
Contents conflict in c2c_budget/c2c_budget.py
Contents conflict in c2c_budget/c2c_budget_item.py
Contents conflict in c2c_budget/c2c_budget_line.py
Contents conflict in c2c_budget/c2c_budget_report_abstraction.py
Contents conflict in c2c_budget/c2c_budget_version.py
Contents conflict in c2c_budget/c2c_budget_view.xml
Contents conflict in c2c_budget/c2c_budget_wizard.xml
Contents conflict in c2c_budget/c2c_budget_wizard_abstraction.py
Conflict: can't delete c2c_budget/report because it is not empty.  Not deleting.
Conflict because c2c_budget/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_budget/report/__init__.py
Contents conflict in c2c_budget/report/budget_by_period.py
Contents conflict in c2c_budget/report/budget_consolidation.py
Contents conflict in c2c_budget/report/budget_vs_reality.py
Contents conflict in c2c_budget/report/compare_versions.py
Contents conflict in c2c_budget/report/helper.py
Conflict: can't delete c2c_budget/wizard because it is not empty.  Not deleting.
Conflict because c2c_budget/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_budget/wizard/__init__.py
Contents conflict in c2c_budget/wizard/advanced_search.py
Contents conflict in c2c_budget/wizard/budget_by_period.py
Contents conflict in c2c_budget/wizard/budget_consolidation.py
Contents conflict in c2c_budget/wizard/budget_vs_reality.py
Contents conflict in c2c_budget/wizard/budgetlines_from_aa.py
Contents conflict in c2c_budget/wizard/compare_versions.py
Contents conflict in c2c_budget/wizard/validate_budget_structure.py
Conflict: can't delete c2c_invoice_report because it is not empty.  Not deleting.
Conflict because c2c_invoice_report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_invoice_report/__init__.py
Contents conflict in c2c_invoice_report/__terp__.py
Conflict: can't delete c2c_invoice_report/i18n because it is not empty.  Not deleting.
Conflict because c2c_invoice_report/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete c2c_invoice_report/report because it is not empty.  Not deleting.
Conflict because c2c_invoice_report/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_invoice_report/report/__init__.py
Contents conflict in c2c_invoice_report/report/invoice.py
Conflict: can't delete c2c_invoice_report/view because it is not empty.  Not deleting.
Conflict because c2c_invoice_report/view is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_invoice_report/view/__init__.py
Contents conflict in c2c_invoice_report/view/invoice.py
Conflict: can't delete c2c_project_activities because it is not empty.  Not deleting.
Conflict because c2c_project_activities is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_project_activities/__init__.py
Contents conflict in c2c_project_activities/__terp__.py
Contents conflict in c2c_project_activities/c2c_project_activities.py
Conflict: can't delete c2c_project_activities/i18n because it is not empty.  Not deleting.
Conflict because c2c_project_activities/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_project_activities/i18n/fr_FR.po
Conflict: can't delete c2c_refresh_so_lines because it is not empty.  Not deleting.
Conflict because c2c_refresh_so_lines is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete c2c_refresh_so_lines/i18n because it is not empty.  Not deleting.
Conflict because c2c_refresh_so_lines/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_refresh_so_lines/sale.py
Conflict: can't delete c2c_reporting_tools because it is not empty.  Not deleting.
Conflict because c2c_reporting_tools is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_reporting_tools/__init__.py
Contents conflict in c2c_reporting_tools/__terp__.py
Contents conflict in c2c_reporting_tools/c2c_helper.py
Contents conflict in c2c_reporting_tools/c2c_osv_debugger.py
Conflict: can't delete c2c_reporting_tools/core because it is not empty.  Not deleting.
Conflict because c2c_reporting_tools/core is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_reporting_tools/core/__init__.py
Contents conflict in c2c_reporting_tools/core/table_elements.py
Conflict: can't delete c2c_reporting_tools/demo because it is not empty.  Not deleting.
Conflict because c2c_reporting_tools/demo is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_reporting_tools/demo/__init__.py
Contents conflict in c2c_reporting_tools/demo/demo.py
Contents conflict in c2c_reporting_tools/demo/hello_world.py
Conflict: can't delete c2c_reporting_tools/flowables because it is not empty.  Not deleting.
Conflict because c2c_reporting_tools/flowables is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_reporting_tools/flowables/__init__.py
Contents conflict in c2c_reporting_tools/flowables/color_legend.py
Contents conflict in c2c_reporting_tools/flowables/key_value_table.py
Contents conflict in c2c_reporting_tools/flowables/simple_row_table.py
Contents conflict in c2c_reporting_tools/flowables/timebox_chart.py
Conflict: can't delete c2c_reporting_tools/reports because it is not empty.  Not deleting.
Conflict because c2c_reporting_tools/reports is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_reporting_tools/reports/__init__.py
Contents conflict in c2c_reporting_tools/reports/standard_report.py
Conflict: can't delete c2c_reporting_tools/templates because it is not empty.  Not deleting.
Conflict because c2c_reporting_tools/templates is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_reporting_tools/templates/__init__.py
Contents conflict in c2c_reporting_tools/templates/standard_template.py
Contents conflict in c2c_reporting_tools/translation.py
Conflict: can't delete c2c_scan_bvr because it is not empty.  Not deleting.
Conflict because c2c_scan_bvr is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_scan_bvr/__init__.py
Contents conflict in c2c_scan_bvr/__terp__.py
Conflict: can't delete c2c_scan_bvr/wizard because it is not empty.  Not deleting.
Conflict because c2c_scan_bvr/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_scan_bvr/wizard/__init__.py
Contents conflict in c2c_scan_bvr/wizard/scan_bvr.py
Conflict: can't delete c2c_timesheet_reports because it is not empty.  Not deleting.
Conflict because c2c_timesheet_reports is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_timesheet_reports/__init__.py
Contents conflict in c2c_timesheet_reports/__terp__.py
Contents conflict in c2c_timesheet_reports/hr_employee.py
Conflict: can't delete c2c_timesheet_reports/i18n because it is not empty.  Not deleting.
Conflict because c2c_timesheet_reports/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_timesheet_reports/reminder.py
Conflict: can't delete c2c_timesheet_reports/report because it is not empty.  Not deleting.
Conflict because c2c_timesheet_reports/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_timesheet_reports/report/__init__.py
Contents conflict in c2c_timesheet_reports/report/timesheet_status.py
Conflict: can't delete c2c_timesheet_reports/wizard because it is not empty.  Not deleting.
Conflict because c2c_timesheet_reports/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in c2c_timesheet_reports/wizard/__init__.py
Contents conflict in c2c_timesheet_reports/wizard/reminder_config.py
Contents conflict in c2c_timesheet_reports/wizard/timesheet_status.py
Conflict: can't delete carrier_picking because it is not empty.  Not deleting.
Conflict because carrier_picking is not versioned, but has versioned children.  Versioned directory.
Contents conflict in carrier_picking/__init__.py
Contents conflict in carrier_picking/__terp__.py
Conflict: can't delete carrier_picking/i18n because it is not empty.  Not deleting.
Conflict because carrier_picking/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in carrier_picking/partner.py
Contents conflict in carrier_picking/stock.py
Conflict: can't delete cci_account because it is not empty.  Not deleting.
Conflict because cci_account is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_account/__init__.py
Contents conflict in cci_account/__terp__.py
Contents conflict in cci_account/cci_account.py
Contents conflict in cci_account/cci_account_report.xml
Contents conflict in cci_account/cci_account_view.xml
Contents conflict in cci_account/cci_account_wizard.xml
Conflict: can't delete cci_account/report because it is not empty.  Not deleting.
Conflict because cci_account/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_account/report/__init__.py
Contents conflict in cci_account/report/aged_trial_balance.py
Contents conflict in cci_account/report/aged_trial_balance.rml
Contents conflict in cci_account/report/aged_trial_balance.sxw
Contents conflict in cci_account/report/cci_draft_invoice_info.py
Contents conflict in cci_account/report/cci_vcs_report.py
Contents conflict in cci_account/report/partner_balance.py
Contents conflict in cci_account/report/partner_balance.rml
Contents conflict in cci_account/report/report_account_invoice_layout.py
Contents conflict in cci_account/report/special_message_invoice.py
Contents conflict in cci_account/report/special_message_invoice.rml
Contents conflict in cci_account/report/special_message_invoice.sxw
Contents conflict in cci_account/report/third_party_ledger.py
Conflict: can't delete cci_account/wizard because it is not empty.  Not deleting.
Conflict because cci_account/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_account/wizard/__init__.py
Contents conflict in cci_account/wizard/cci_switched_debit_credit.py
Contents conflict in cci_account/wizard/cci_use_model.py
Contents conflict in cci_account/wizard/cci_wizard_aged_trial_balance.py
Contents conflict in cci_account/wizard/cci_wizard_partner_balance_report.py
Contents conflict in cci_account/wizard/cci_wizard_third_party_ledger.py
Contents conflict in cci_account/wizard/cci_wizard_vcs.py
Contents conflict in cci_account/wizard/invoice_special_message.py
Conflict: can't delete cci_audittrail because it is not empty.  Not deleting.
Conflict because cci_audittrail is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_audittrail/__init__.py
Contents conflict in cci_audittrail/__terp__.py
Contents conflict in cci_audittrail/audittrail.py
Conflict: can't delete cci_base_contact because it is not empty.  Not deleting.
Conflict because cci_base_contact is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_base_contact/__init__.py
Contents conflict in cci_base_contact/__terp__.py
Contents conflict in cci_base_contact/cci_base_contact.py
Contents conflict in cci_base_contact/cci_base_contact_view.xml
Conflict: can't delete cci_country because it is not empty.  Not deleting.
Conflict because cci_country is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_country/__init__.py
Contents conflict in cci_country/__terp__.py
Contents conflict in cci_country/cci_country.py
Conflict: can't delete cci_crm because it is not empty.  Not deleting.
Conflict because cci_crm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_crm/__init__.py
Contents conflict in cci_crm/__terp__.py
Contents conflict in cci_crm/cci_crm.py
Contents conflict in cci_crm/cci_crm_data.xml
Contents conflict in cci_crm/cci_crm_view.xml
Conflict: can't delete cci_crm_profile because it is not empty.  Not deleting.
Conflict because cci_crm_profile is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_crm_profile/__init__.py
Contents conflict in cci_crm_profile/__terp__.py
Contents conflict in cci_crm_profile/cci_crm_profile.py
Contents conflict in cci_crm_profile/cci_crm_profile_view.xml
Conflict: can't delete cci_data_csv because it is not empty.  Not deleting.
Conflict because cci_data_csv is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_data_csv/__init__.py
Contents conflict in cci_data_csv/__terp__.py
Conflict: can't delete cci_event because it is not empty.  Not deleting.
Conflict because cci_event is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_event/__init__.py
Contents conflict in cci_event/__terp__.py
Contents conflict in cci_event/cci_event.py
Contents conflict in cci_event/cci_event_view.xml
Contents conflict in cci_event/cci_event_wizard.xml
Conflict: can't delete cci_event/wizard because it is not empty.  Not deleting.
Conflict because cci_event/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_event/wizard/__init__.py
Contents conflict in cci_event/wizard/event_copy.py
Contents conflict in cci_event/wizard/registration_missing_checks.py
Conflict: can't delete cci_membership because it is not empty.  Not deleting.
Conflict because cci_membership is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_membership/__init__.py
Contents conflict in cci_membership/__terp__.py
Contents conflict in cci_membership/cci_membership.py
Contents conflict in cci_membership/cci_membership_view.xml
Contents conflict in cci_membership/cci_membership_wizard.xml
Conflict: can't delete cci_membership/report because it is not empty.  Not deleting.
Conflict because cci_membership/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_membership/report/__init__.py
Contents conflict in cci_membership/report/report_members_total_sold.py
Conflict: can't delete cci_membership/security because it is not empty.  Not deleting.
Conflict because cci_membership/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_membership/security/ir.model.access.csv
Conflict: can't delete cci_membership/wizard because it is not empty.  Not deleting.
Conflict because cci_membership/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_membership/wizard/__init__.py
Contents conflict in cci_membership/wizard/members_total_sold.py
Contents conflict in cci_membership/wizard/show_partners.py
Conflict: can't delete cci_mission because it is not empty.  Not deleting.
Conflict because cci_mission is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_mission/__init__.py
Contents conflict in cci_mission/__terp__.py
Contents conflict in cci_mission/cci_mission.py
Contents conflict in cci_mission/cci_mission_report.xml
Contents conflict in cci_mission/cci_mission_view.xml
Contents conflict in cci_mission/cci_mission_wizard.xml
Contents conflict in cci_mission/cci_mission_workflow.xml
Conflict: can't delete cci_mission/report because it is not empty.  Not deleting.
Conflict because cci_mission/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_mission/report/__init__.py
Contents conflict in cci_mission/report/report_print_carnet.py
Conflict: can't delete cci_mission/wizard because it is not empty.  Not deleting.
Conflict because cci_mission/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_mission/wizard/__init__.py
Contents conflict in cci_mission/wizard/cci_encode_cash.py
Contents conflict in cci_mission/wizard/create_invoice.py
Contents conflict in cci_mission/wizard/create_invoice_carnet.py
Contents conflict in cci_mission/wizard/create_invoice_embassy.py
Contents conflict in cci_mission/wizard/make_invoice_group.py
Contents conflict in cci_mission/wizard/wizard_create_embassy_folder.py
Contents conflict in cci_mission/wizard/wizard_federation_certificates_sending.py
Contents conflict in cci_mission/wizard/wizard_federation_sending.py
Contents conflict in cci_mission/wizard/wizard_print_carnet.py
Contents conflict in cci_mission/wizard/wizard_simulation_carnet.py
Conflict: can't delete cci_partner because it is not empty.  Not deleting.
Conflict because cci_partner is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_partner/__init__.py
Contents conflict in cci_partner/__terp__.py
Contents conflict in cci_partner/cci_data.xml
Contents conflict in cci_partner/cci_partner.py
Contents conflict in cci_partner/cci_partner_view.xml
Contents conflict in cci_partner/cci_partner_wizard.xml
Conflict: can't delete cci_partner/report because it is not empty.  Not deleting.
Conflict because cci_partner/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_partner/report/__init__.py
Contents conflict in cci_partner/report/report_count_invoices.py
Conflict: can't delete cci_partner/security because it is not empty.  Not deleting.
Conflict because cci_partner/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_partner/security/ir.model.access.csv
Contents conflict in cci_partner/security/security.xml
Conflict: can't delete cci_partner/wizard because it is not empty.  Not deleting.
Conflict because cci_partner/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_partner/wizard/__init__.py
Contents conflict in cci_partner/wizard/cci_partner_event_history.py
Contents conflict in cci_partner/wizard/cci_wizard_sms.py
Contents conflict in cci_partner/wizard/cci_wizard_spam.py
Conflict: can't delete cci_purchase because it is not empty.  Not deleting.
Conflict because cci_purchase is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_purchase/__init__.py
Contents conflict in cci_purchase/__terp__.py
Contents conflict in cci_purchase/cci_purchase.py
Contents conflict in cci_purchase/cci_purchase_view.xml
Contents conflict in cci_purchase/cci_purchase_workflow.xml
Conflict: can't delete cci_sales because it is not empty.  Not deleting.
Conflict because cci_sales is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_sales/__init__.py
Contents conflict in cci_sales/__terp__.py
Contents conflict in cci_sales/cci_sales.py
Contents conflict in cci_sales/cci_sales_view.xml
Conflict: can't delete cci_security because it is not empty.  Not deleting.
Conflict because cci_security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_security/__terp__.py
Contents conflict in cci_security/import.py
Conflict: can't delete cci_timesheet because it is not empty.  Not deleting.
Conflict because cci_timesheet is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_timesheet/__init__.py
Contents conflict in cci_timesheet/__terp__.py
Contents conflict in cci_timesheet/cci_timesheet.py
Contents conflict in cci_timesheet/cci_timesheet_view.xml
Conflict: can't delete cci_timesheet/wizard because it is not empty.  Not deleting.
Conflict because cci_timesheet/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_timesheet/wizard/__init__.py
Contents conflict in cci_timesheet/wizard/create_timesheet_line.py
Conflict: can't delete cci_translation because it is not empty.  Not deleting.
Conflict because cci_translation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_translation/__init__.py
Contents conflict in cci_translation/__terp__.py
Contents conflict in cci_translation/cci_translation.py
Contents conflict in cci_translation/cci_translation_view.xml
Contents conflict in cci_translation/cci_translation_wizard.xml
Conflict: can't delete cci_translation/wizard because it is not empty.  Not deleting.
Conflict because cci_translation/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cci_translation/wizard/__init__.py
Contents conflict in cci_translation/wizard/make_invoice.py
Conflict: can't delete chemical because it is not empty.  Not deleting.
Conflict because chemical is not versioned, but has versioned children.  Versioned directory.
Contents conflict in chemical/__init__.py
Contents conflict in chemical/__terp__.py
Contents conflict in chemical/chemical.py
Conflict: can't delete chemical/product because it is not empty.  Not deleting.
Conflict because chemical/product is not versioned, but has versioned children.  Versioned directory.
Contents conflict in chemical/product/__init__.py
Contents conflict in chemical/product/product_view_chem.xml
Contents conflict in chemical/product/risque_securite_danger.py
Conflict: can't delete chricar_partner_parent_companies because it is not empty.  Not deleting.
Conflict because chricar_partner_parent_companies is not versioned, but has versioned children.  Versioned directory.
Contents conflict in chricar_partner_parent_companies/__init__.py
Contents conflict in chricar_partner_parent_companies/__terp__.py
Conflict: can't delete chricar_partner_parent_companies/i18n because it is not empty.  Not deleting.
Conflict because chricar_partner_parent_companies/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete chricar_product_gtin because it is not empty.  Not deleting.
Conflict because chricar_product_gtin is not versioned, but has versioned children.  Versioned directory.
Contents conflict in chricar_product_gtin/__init__.py
Contents conflict in chricar_product_gtin/chricar_product_gtin.py
Conflict: can't delete chricar_product_gtin/i18n because it is not empty.  Not deleting.
Conflict because chricar_product_gtin/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete chricar_product_image because it is not empty.  Not deleting.
Conflict because chricar_product_image is not versioned, but has versioned children.  Versioned directory.
Contents conflict in chricar_product_image/__init__.py
Contents conflict in chricar_product_image/__terp__.py
Contents conflict in chricar_product_image/chricar_product_image.py
Conflict: can't delete chricar_product_image/i18n because it is not empty.  Not deleting.
Conflict because chricar_product_image/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete city because it is not empty.  Not deleting.
Conflict because city is not versioned, but has versioned children.  Versioned directory.
Contents conflict in city/city.py
Contents conflict in city/city_view.xml
Conflict: can't delete city/i18n because it is not empty.  Not deleting.
Conflict because city/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete commission because it is not empty.  Not deleting.
Conflict because commission is not versioned, but has versioned children.  Versioned directory.
Contents conflict in commission/__init__.py
Contents conflict in commission/__terp__.py
Contents conflict in commission/commission.py
Contents conflict in commission/commission_sequence.xml
Contents conflict in commission/commission_view.xml
Contents conflict in commission/partner.py
Contents conflict in commission/partner_view.xml
Contents conflict in commission/pricelist.py
Contents conflict in commission/pricelist_view.xml
Conflict: can't delete commission/report because it is not empty.  Not deleting.
Conflict because commission/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in commission/report/__init__.py
Contents conflict in commission/report/saleagent_info.py
Contents conflict in commission/saleagent.py
Contents conflict in commission/saleagent_demo.xml
Contents conflict in commission/saleagent_sequence.xml
Contents conflict in commission/saleagent_view.xml
Conflict: can't delete commission/security because it is not empty.  Not deleting.
Conflict because commission/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in commission/security/ir.model.access.csv
Conflict: can't delete commission/wizard because it is not empty.  Not deleting.
Conflict because commission/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in commission/wizard/__init__.py
Contents conflict in commission/wizard/all_commission.py
Contents conflict in commission/wizard/saleagent_info_wizard.py
Contents conflict in commission/wizard/wizard_commission.py
Conflict: can't delete comparison because it is not empty.  Not deleting.
Conflict because comparison is not versioned, but has versioned children.  Versioned directory.
Contents conflict in comparison/__openerp__.py
Contents conflict in comparison/comparison.py
Contents conflict in comparison/comparison_view.xml
Conflict: can't delete comparison/i18n because it is not empty.  Not deleting.
Conflict because comparison/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete comparison/website because it is not empty.  Not deleting.
Conflict because comparison/website is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete comparison/website/erpComparator because it is not empty.  Not deleting.
Conflict because comparison/website/erpComparator is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete comparison/website/erpComparator/erpcomparator because it is not empty.  Not deleting.
Conflict because comparison/website/erpComparator/erpcomparator is not versioned, but has versioned children.  Versioned directory.
Contents conflict in comparison/website/erpComparator/erpcomparator/common.py
Conflict: can't delete comparison/website/erpComparator/erpcomparator/config because it is not empty.  Not deleting.
Conflict because comparison/website/erpComparator/erpcomparator/config is not versioned, but has versioned children.  Versioned directory.
Contents conflict in comparison/website/erpComparator/erpcomparator/config/__init__.py
Contents conflict in comparison/website/erpComparator/erpcomparator/rpc.py
Conflict: can't delete comparison/website/erpComparator/erpcomparator/static because it is not empty.  Not deleting.
Conflict because comparison/website/erpComparator/erpcomparator/static is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete comparison/website/erpComparator/erpcomparator/static/planet_comparison because it is not empty.  Not deleting.
Conflict because comparison/website/erpComparator/erpcomparator/static/planet_comparison is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet because it is not empty.  Not deleting.
Conflict because comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet is not versioned, but has versioned children.  Versioned directory.
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet-cache.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/__init__.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/atomstyler.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/cache.py
Conflict: can't delete comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/compat_logging because it is not empty.  Not deleting.
Conflict because comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/compat_logging is not versioned, but has versioned children.  Versioned directory.
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/compat_logging/handlers.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/feedparser.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/htmltmpl.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/sanitize.py
Contents conflict in comparison/website/erpComparator/erpcomparator/static/planet_comparison/planet/timeoutsocket.py
Conflict: can't delete comparison/wizard because it is not empty.  Not deleting.
Conflict because comparison/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in comparison/wizard/__init__.py
Contents conflict in comparison/wizard/comparison_recompute_evaluations.py
Conflict: can't delete crm_bayes because it is not empty.  Not deleting.
Conflict because crm_bayes is not versioned, but has versioned children.  Versioned directory.
Contents conflict in crm_bayes/__init__.py
Contents conflict in crm_bayes/__terp__.py
Contents conflict in crm_bayes/crm_bayes.py
Contents conflict in crm_bayes/crm_bayes_demo.xml
Contents conflict in crm_bayes/crm_bayes_view.xml
Conflict: can't delete crm_livechat because it is not empty.  Not deleting.
Conflict because crm_livechat is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete crm_livechat/crm-lc because it is not empty.  Not deleting.
Conflict because crm_livechat/crm-lc is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete crm_livechat/crm-lc/livechat because it is not empty.  Not deleting.
Conflict because crm_livechat/crm-lc/livechat is not versioned, but has versioned children.  Versioned directory.
Contents conflict in crm_livechat/crm-lc/livechat/common.py
Contents conflict in crm_livechat/crm-lc/livechat/controllers.py
Contents conflict in crm_livechat/crm-lc/livechat/debug.py
Contents conflict in crm_livechat/crm-lc/livechat/rpc.py
Conflict: can't delete crm_livechat/crm-lc/livechat/subcontrollers because it is not empty.  Not deleting.
Conflict because crm_livechat/crm-lc/livechat/subcontrollers is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete crm_livechat/crm-lc/livechat/subcontrollers/livechat because it is not empty.  Not deleting.
Conflict because crm_livechat/crm-lc/livechat/subcontrollers/livechat is not versioned, but has versioned children.  Versioned directory.
Contents conflict in crm_livechat/crm-lc/livechat/subcontrollers/livechat/chatfunc.py
Contents conflict in crm_livechat/crm-lc/livechat/xmlstream.py
Contents conflict in crm_livechat/crm_livechat.py
Conflict: can't delete crm_telemarketing because it is not empty.  Not deleting.
Conflict because crm_telemarketing is not versioned, but has versioned children.  Versioned directory.
Contents conflict in crm_telemarketing/__init__.py
Contents conflict in crm_telemarketing/__terp__.py
Contents conflict in crm_telemarketing/crm_telemarketing.py
Conflict: can't delete crm_telemarketing/i18n because it is not empty.  Not deleting.
Conflict because crm_telemarketing/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete crm_telemarketing/report because it is not empty.  Not deleting.
Conflict because crm_telemarketing/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in crm_telemarketing/report/__init__.py
Conflict: can't delete crm_telemarketing/wizard because it is not empty.  Not deleting.
Conflict because crm_telemarketing/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in crm_telemarketing/wizard/__init__.py
Contents conflict in crm_telemarketing/wizard/create_call_list.py
Contents conflict in crm_telemarketing/wizard/direct_poll.py
Contents conflict in crm_telemarketing/wizard/meeting_planify.py
Conflict: can't delete currency_rate because it is not empty.  Not deleting.
Conflict because currency_rate is not versioned, but has versioned children.  Versioned directory.
Contents conflict in currency_rate/__init__.py
Contents conflict in currency_rate/__terp__.py
Contents conflict in currency_rate/res_currency.py
Conflict: can't delete currency_rate/wizard because it is not empty.  Not deleting.
Conflict because currency_rate/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in currency_rate/wizard/__init__.py
Contents conflict in currency_rate/wizard/currency_rate.py
Conflict: can't delete currency_rate_update because it is not empty.  Not deleting.
Path conflict: currency_rate_update / <deleted>
Conflict because currency_rate_update is not versioned, but has versioned children.  Versioned directory.
Contents conflict in currency_rate_update/__init__.py
Contents conflict in currency_rate_update/company.py
Contents conflict in currency_rate_update/company_view.xml
Contents conflict in currency_rate_update/currency_rate_update.py
Contents conflict in currency_rate_update/currency_rate_update.xml
Conflict: can't delete currency_rate_update/security because it is not empty.  Not deleting.
Conflict because currency_rate_update/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in currency_rate_update/security/security.xml
Conflict: can't delete demo_setup because it is not empty.  Not deleting.
Conflict because demo_setup is not versioned, but has versioned children.  Versioned directory.
Contents conflict in demo_setup/__init__.py
Contents conflict in demo_setup/__terp__.py
Conflict: can't delete demo_setup/i18n because it is not empty.  Not deleting.
Conflict because demo_setup/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete discount_campaign because it is not empty.  Not deleting.
Conflict because discount_campaign is not versioned, but has versioned children.  Versioned directory.
Contents conflict in discount_campaign/__init__.py
Contents conflict in discount_campaign/__terp__.py
Contents conflict in discount_campaign/discount_campaign.py
Contents conflict in discount_campaign/discount_campaign_view.xml
Conflict: can't delete discount_campaign/security because it is not empty.  Not deleting.
Conflict because discount_campaign/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in discount_campaign/security/ir.model.access.csv
Conflict: can't delete dm because it is not empty.  Not deleting.
Conflict because dm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm/__init__.py
Contents conflict in dm/__terp__.py
Contents conflict in dm/dm_campaign.py
Contents conflict in dm/dm_campaign_view.xml
Contents conflict in dm/dm_data.xml
Contents conflict in dm/dm_demo.xml
Contents conflict in dm/dm_document.py
Contents conflict in dm/dm_document_view.xml
Contents conflict in dm/dm_engine.py
Contents conflict in dm/dm_engine_view.xml
Contents conflict in dm/dm_inherit.py
Contents conflict in dm/dm_inherit_view.xml
Contents conflict in dm/dm_offer.py
Contents conflict in dm/dm_offer_step.py
Contents conflict in dm/dm_offer_step_view.xml
Contents conflict in dm/dm_offer_view.xml
Contents conflict in dm/dm_report.xml
Contents conflict in dm/dm_report_design.py
Contents conflict in dm/dm_wizard.xml
Contents conflict in dm/dm_workflow.xml
Conflict: can't delete dm/i18n because it is not empty.  Not deleting.
Conflict because dm/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm/i18n/fr_FR.po
Conflict: can't delete dm/plugin because it is not empty.  Not deleting.
Conflict because dm/plugin is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm/plugin/__init__.py
Contents conflict in dm/plugin/current_time.py
Contents conflict in dm/plugin/customer_function.py
Contents conflict in dm/plugin/dynamic_text.py
Contents conflict in dm/plugin/php_url.py
Conflict: can't delete dm/report because it is not empty.  Not deleting.
Conflict because dm/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm/report/__init__.py
Contents conflict in dm/report/dm_campaign.rml
Contents conflict in dm/report/dm_campaign_report.py
Contents conflict in dm/report/dm_document_report.py
Contents conflict in dm/report/dm_ir_action_report.py
Contents conflict in dm/report/dm_offer.rml
Contents conflict in dm/report/dm_offer.sxw
Contents conflict in dm/report/dm_offer_report.py
Contents conflict in dm/report/dm_print_offer_graph.py
Contents conflict in dm/report/pkg_insert_doc09_report.rml
Contents conflict in dm/report/pkg_insert_doc09_report.sxw
Conflict: can't delete dm/security because it is not empty.  Not deleting.
Conflict because dm/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm/security/dm_security.xml
Contents conflict in dm/security/ir.model.access.csv
Conflict: can't delete dm/wizard because it is not empty.  Not deleting.
Conflict because dm/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm/wizard/__init__.py
Contents conflict in dm/wizard/dm_address_after_sale_action.py
Contents conflict in dm/wizard/dm_all_document_report.py
Contents conflict in dm/wizard/dm_campaign_copy.py
Contents conflict in dm/wizard/dm_document_report.py
Contents conflict in dm/wizard/dm_offer_document.py
Contents conflict in dm/wizard/dm_partner_address_segments.py
Contents conflict in dm/wizard/dm_proposition_copy.py
Contents conflict in dm/wizard/dm_so_after_sale_action.py
Contents conflict in dm/wizard/dm_workitem_wizard.py
Conflict: can't delete dm_after_sale because it is not empty.  Not deleting.
Conflict because dm_after_sale is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_after_sale/__init__.py
Contents conflict in dm_after_sale/__terp__.py
Contents conflict in dm_after_sale/dm_after_sale.py
Contents conflict in dm_after_sale/dm_after_sale_view.xml
Conflict: can't delete dm_after_sale/security because it is not empty.  Not deleting.
Conflict because dm_after_sale/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_after_sale/security/ir.model.access.csv
Conflict: can't delete dm_base_contact because it is not empty.  Not deleting.
Conflict because dm_base_contact is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_base_contact/__init__.py
Contents conflict in dm_base_contact/__terp__.py
Conflict: can't delete dm_campaign_group because it is not empty.  Not deleting.
Conflict because dm_campaign_group is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_campaign_group/__init__.py
Contents conflict in dm_campaign_group/__terp__.py
Contents conflict in dm_campaign_group/dm_campaign_group.py
Contents conflict in dm_campaign_group/dm_campaign_group_view.xml
Conflict: can't delete dm_campaign_group/i18n because it is not empty.  Not deleting.
Conflict because dm_campaign_group/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete dm_campaign_group/wizard because it is not empty.  Not deleting.
Conflict because dm_campaign_group/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_campaign_group/wizard/__init__.py
Contents conflict in dm_campaign_group/wizard/dm_campaign_group.py
Conflict: can't delete dm_delivery because it is not empty.  Not deleting.
Conflict because dm_delivery is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_delivery/__init__.py
Contents conflict in dm_delivery/__terp__.py
Contents conflict in dm_delivery/dm_delivery.py
Contents conflict in dm_delivery/dm_delivery_data.xml
Conflict: can't delete dm_document because it is not empty.  Not deleting.
Conflict because dm_document is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_document/__init__.py
Contents conflict in dm_document/__terp__.py
Conflict: can't delete dm_emailvision because it is not empty.  Not deleting.
Conflict because dm_emailvision is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_emailvision/__init__.py
Contents conflict in dm_emailvision/__terp__.py
Contents conflict in dm_emailvision/dm_emailvision_api.py
Contents conflict in dm_emailvision/dm_emailvision_data.xml
Contents conflict in dm_emailvision/dm_emailvision_view.xml
Conflict: can't delete dm_extract because it is not empty.  Not deleting.
Conflict because dm_extract is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_extract/__init__.py
Contents conflict in dm_extract/__terp__.py
Contents conflict in dm_extract/dm_extract.py
Contents conflict in dm_extract/dm_extract_data.xml
Contents conflict in dm_extract/dm_extract_view.xml
Conflict: can't delete dm_extract_sale because it is not empty.  Not deleting.
Conflict because dm_extract_sale is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_extract_sale/__init__.py
Contents conflict in dm_extract_sale/__terp__.py
Contents conflict in dm_extract_sale/dm_extract_sale.py
Contents conflict in dm_extract_sale/dm_extract_sale_view.xml
Conflict: can't delete dm_lead because it is not empty.  Not deleting.
Conflict because dm_lead is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_lead/__init__.py
Contents conflict in dm_lead/__terp__.py
Contents conflict in dm_lead/dm_lead.py
Contents conflict in dm_lead/dm_lead_data.xml
Contents conflict in dm_lead/dm_lead_view.xml
Conflict: can't delete dm_partner_address because it is not empty.  Not deleting.
Conflict because dm_partner_address is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_partner_address/__init__.py
Contents conflict in dm_partner_address/__terp__.py
Contents conflict in dm_partner_address/dm_partner_address.py
Contents conflict in dm_partner_address/dm_partner_address_view.xml
Conflict: can't delete dm_payment_rules because it is not empty.  Not deleting.
Conflict because dm_payment_rules is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete dm_price_progression because it is not empty.  Not deleting.
Conflict because dm_price_progression is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_price_progression/__init__.py
Contents conflict in dm_price_progression/__terp__.py
Contents conflict in dm_price_progression/dm_price_progression.py
Contents conflict in dm_price_progression/dm_price_progression_view.xml
Conflict: can't delete dm_price_progression/i18n because it is not empty.  Not deleting.
Conflict because dm_price_progression/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete dm_price_progression/wizard because it is not empty.  Not deleting.
Conflict because dm_price_progression/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_price_progression/wizard/__init__.py
Contents conflict in dm_price_progression/wizard/dm_proposition_products.py
Conflict: can't delete dm_purchase because it is not empty.  Not deleting.
Conflict because dm_purchase is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_purchase/__init__.py
Contents conflict in dm_purchase/__terp__.py
Contents conflict in dm_purchase/dm_purchase.py
Contents conflict in dm_purchase/dm_purchase_view.xml
Conflict: can't delete dm_purchase_advanced because it is not empty.  Not deleting.
Conflict because dm_purchase_advanced is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_purchase_advanced/__init__.py
Contents conflict in dm_purchase_advanced/__terp__.py
Contents conflict in dm_purchase_advanced/dm_purchase_advanced.py
Contents conflict in dm_purchase_advanced/dm_purchase_advanced_view.xml
Conflict: can't delete dm_purchase_advanced/security because it is not empty.  Not deleting.
Conflict because dm_purchase_advanced/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_purchase_advanced/security/ir.model.access.csv
Conflict: can't delete dm_retro_planning because it is not empty.  Not deleting.
Conflict because dm_retro_planning is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_retro_planning/__init__.py
Contents conflict in dm_retro_planning/__terp__.py
Contents conflict in dm_retro_planning/dm_retro_planning.py
Contents conflict in dm_retro_planning/dm_retro_planning_view.xml
Conflict: can't delete dm_retro_planning/security because it is not empty.  Not deleting.
Conflict because dm_retro_planning/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_retro_planning/security/ir.model.access.csv
Conflict: can't delete dm_retro_planning/wizard because it is not empty.  Not deleting.
Conflict because dm_retro_planning/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_retro_planning/wizard/__init__.py
Contents conflict in dm_retro_planning/wizard/dm_campaign_group_project.py
Contents conflict in dm_retro_planning/wizard/dm_campaign_group_tasks.py
Contents conflict in dm_retro_planning/wizard/dm_campaign_project.py
Contents conflict in dm_retro_planning/wizard/dm_campaign_tasks.py
Conflict: can't delete dm_sale because it is not empty.  Not deleting.
Conflict because dm_sale is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_sale/__init__.py
Contents conflict in dm_sale/__terp__.py
Contents conflict in dm_sale/dm_sale.py
Contents conflict in dm_sale/dm_sale_data.xml
Contents conflict in dm_sale/dm_sale_demo.xml
Contents conflict in dm_sale/dm_sale_view.xml
Conflict: can't delete dm_simulator because it is not empty.  Not deleting.
Conflict because dm_simulator is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_simulator/__init__.py
Contents conflict in dm_simulator/__terp__.py
Contents conflict in dm_simulator/dm_simulator.py
Contents conflict in dm_simulator/dm_simulator_demo.xml
Contents conflict in dm_simulator/dm_simulator_view.xml
Conflict: can't delete dm_website because it is not empty.  Not deleting.
Conflict because dm_website is not versioned, but has versioned children.  Versioned directory.
Contents conflict in dm_website/__init__.py
Contents conflict in dm_website/__terp__.py
Contents conflict in dm_website/dm_website.py
Contents conflict in dm_website/dm_website_data.xml
Contents conflict in dm_website/dm_website_demo.xml
Contents conflict in dm_website/dm_website_view.xml
Conflict: can't delete document_extension because it is not empty.  Not deleting.
Conflict because document_extension is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_extension/__init__.py
Contents conflict in document_extension/__terp__.py
Contents conflict in document_extension/document.py
Conflict: can't delete document_lock because it is not empty.  Not deleting.
Conflict because document_lock is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_lock/__init__.py
Contents conflict in document_lock/__terp__.py
Contents conflict in document_lock/document_lock.py
Conflict: can't delete document_no_contentindex because it is not empty.  Not deleting.
Conflict because document_no_contentindex is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_no_contentindex/__init__.py
Contents conflict in document_no_contentindex/__terp__.py
Contents conflict in document_no_contentindex/document_no_contentindex.py
Conflict: can't delete document_rule because it is not empty.  Not deleting.
Conflict because document_rule is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_rule/__init__.py
Contents conflict in document_rule/__terp__.py
Contents conflict in document_rule/document_rule.py
Conflict: can't delete document_sftp because it is not empty.  Not deleting.
Conflict because document_sftp is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_sftp/__init__.py
Contents conflict in document_sftp/__terp__.py
Contents conflict in document_sftp/document.py
Conflict: can't delete document_sftp/sftp_server because it is not empty.  Not deleting.
Conflict because document_sftp/sftp_server is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_sftp/sftp_server/SFTPServer.py
Contents conflict in document_sftp/sftp_server/SFTPServerInterface.py
Contents conflict in document_sftp/sftp_server/Server.py
Contents conflict in document_sftp/sftp_server/__init__.py
Conflict: can't delete document_webdav_old because it is not empty.  Not deleting.
Conflict because document_webdav_old is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_webdav_old/__init__.py
Contents conflict in document_webdav_old/__terp__.py
Contents conflict in document_webdav_old/document.py
Conflict: can't delete document_webdav_old/webdav because it is not empty.  Not deleting.
Conflict because document_webdav_old/webdav is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete document_webdav_old/webdav/DAV because it is not empty.  Not deleting.
Conflict because document_webdav_old/webdav/DAV is not versioned, but has versioned children.  Versioned directory.
Contents conflict in document_webdav_old/webdav/DAV/WebDAVServer.py
Contents conflict in document_webdav_old/webdav/__init__.py
Contents conflict in document_webdav_old/webdav/cache.py
Contents conflict in document_webdav_old/webdav/content_index.py
Contents conflict in document_webdav_old/webdav/dav_auth.py
Contents conflict in document_webdav_old/webdav/dav_fs.py
Contents conflict in document_webdav_old/webdav/odt2txt.py
Contents conflict in document_webdav_old/webdav/webdav_server.py
Conflict: can't delete ecommerce because it is not empty.  Not deleting.
Conflict because ecommerce is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete ecommerce/catalog because it is not empty.  Not deleting.
Conflict because ecommerce/catalog is not versioned, but has versioned children.  Versioned directory.
Contents conflict in ecommerce/catalog/__init__.py
Contents conflict in ecommerce/catalog/catalog.py
Contents conflict in ecommerce/ecommerce_view.xml
Conflict: can't delete ecommerce/partner because it is not empty.  Not deleting.
Conflict because ecommerce/partner is not versioned, but has versioned children.  Versioned directory.
Contents conflict in ecommerce/partner/__init__.py
Contents conflict in ecommerce/partner/partner.py
Conflict: can't delete ecommerce/report because it is not empty.  Not deleting.
Conflict because ecommerce/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in ecommerce/report/__init__.py
Conflict: can't delete ecommerce/sale_order because it is not empty.  Not deleting.
Conflict because ecommerce/sale_order is not versioned, but has versioned children.  Versioned directory.
Contents conflict in ecommerce/sale_order/sale_order.py
Conflict: can't delete edi because it is not empty.  Not deleting.
Conflict because edi is not versioned, but has versioned children.  Versioned directory.
Contents conflict in edi/__init__.py
Contents conflict in edi/__terp__.py
Contents conflict in edi/edi.py
Contents conflict in edi/partner.py
Contents conflict in edi/sale_cust_price.py
Conflict: can't delete edi/wizard because it is not empty.  Not deleting.
Conflict because edi/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in edi/wizard/__init__.py
Contents conflict in edi/wizard/edi_exchange.py
Contents conflict in edi/wizard/wizard_edi_export.py
Contents conflict in edi/wizard/wizard_edi_import.py
Conflict: can't delete electronic_report_intrastat because it is not empty.  Not deleting.
Conflict because electronic_report_intrastat is not versioned, but has versioned children.  Versioned directory.
Contents conflict in electronic_report_intrastat/__init__.py
Contents conflict in electronic_report_intrastat/__terp__.py
Contents conflict in electronic_report_intrastat/report_intrastat.py
Conflict: can't delete electronic_report_intrastat/wizard because it is not empty.  Not deleting.
Conflict because electronic_report_intrastat/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in electronic_report_intrastat/wizard/__init__.py
Contents conflict in electronic_report_intrastat/wizard/wizard_intrastat_export.py
Conflict: can't delete email_account because it is not empty.  Not deleting.
Conflict because email_account is not versioned, but has versioned children.  Versioned directory.
Contents conflict in email_account/__openerp__.py
Conflict: can't delete email_account/i18n because it is not empty.  Not deleting.
Conflict because email_account/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete email_account/wizard because it is not empty.  Not deleting.
Conflict because email_account/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in email_account/wizard/wizard_send_email.py
Conflict: can't delete email_sale because it is not empty.  Not deleting.
Conflict because email_sale is not versioned, but has versioned children.  Versioned directory.
Contents conflict in email_sale/__openerp__.py
Conflict: can't delete email_sale/i18n because it is not empty.  Not deleting.
Conflict because email_sale/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in email_sale/i18n/email_sale.pot
Conflict: can't delete email_sale/wizard because it is not empty.  Not deleting.
Conflict because email_sale/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in email_sale/wizard/wizard_send_email.py
Conflict: can't delete esale_ez because it is not empty.  Not deleting.
Conflict because esale_ez is not versioned, but has versioned children.  Versioned directory.
Contents conflict in esale_ez/__init__.py
Contents conflict in esale_ez/__terp__.py
Contents conflict in esale_ez/esale.py
Conflict: can't delete esale_joomla because it is not empty.  Not deleting.
Conflict because esale_joomla is not versioned, but has versioned children.  Versioned directory.
Contents conflict in esale_joomla/__terp__.py
Conflict: can't delete esale_joomla/connector because it is not empty.  Not deleting.
Conflict because esale_joomla/connector is not versioned, but has versioned children.  Versioned directory.
Contents conflict in esale_joomla/esale_joomla.py
Contents conflict in esale_joomla/esale_joomla_view.xml
Contents conflict in esale_joomla/esale_joomla_wizard.xml
Conflict: can't delete esale_joomla/wizard because it is not empty.  Not deleting.
Conflict because esale_joomla/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in esale_joomla/wizard/__init__.py
Contents conflict in esale_joomla/wizard/wizard_esale_import.py
Contents conflict in esale_joomla/wizard/wizard_product_stock.py
Contents conflict in esale_joomla/wizard/wizard_taxes_export.py
Conflict: can't delete esale_osc because it is not empty.  Not deleting.
Conflict because esale_osc is not versioned, but has versioned children.  Versioned directory.
Contents conflict in esale_osc/esale_oscom.py
Contents conflict in esale_osc/esale_oscom_product.py
Conflict: can't delete esale_osc/i18n because it is not empty.  Not deleting.
Conflict because esale_osc/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete esale_osc/wizard because it is not empty.  Not deleting.
Conflict because esale_osc/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in esale_osc/wizard/wizard_esale_oscom_export_products.py
Contents conflict in esale_osc/wizard/wizard_esale_oscom_export_select_products.py
Contents conflict in esale_osc/wizard/wizard_esale_oscom_update_select_stocks.py
Conflict: can't delete etl because it is not empty.  Not deleting.
Conflict because etl is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete etl/lib because it is not empty.  Not deleting.
Conflict because etl/lib is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete etl/lib/demo because it is not empty.  Not deleting.
Conflict because etl/lib/demo is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/demo/category_test.py
Contents conflict in etl/lib/demo/facebook_openerp.py
Contents conflict in etl/lib/demo/gcalendar_openerp.py
Contents conflict in etl/lib/demo/gdoc_test.py
Conflict: can't delete etl/lib/demo/input because it is not empty.  Not deleting.
Conflict because etl/lib/demo/input is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/demo/join.py
Contents conflict in etl/lib/demo/m2m_into_oo.py
Contents conflict in etl/lib/demo/map.py
Contents conflict in etl/lib/demo/openerp_facebook.py
Conflict: can't delete etl/lib/demo/salesforce_crm because it is not empty.  Not deleting.
Conflict because etl/lib/demo/salesforce_crm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/demo/salesforce_crm/beatbox.py
Contents conflict in etl/lib/demo/salesforce_crm/demo.py
Contents conflict in etl/lib/demo/salesforce_crm/export.py
Contents conflict in etl/lib/demo/salesforce_crm/soql2atom.py
Contents conflict in etl/lib/demo/salesforce_crm/xmltramp.py
Contents conflict in etl/lib/demo/subjob.py
Contents conflict in etl/lib/demo/subjob2.py
Contents conflict in etl/lib/demo/sugercrm_openerp.py
Contents conflict in etl/lib/demo/test1.py
Contents conflict in etl/lib/demo/test2.py
Contents conflict in etl/lib/demo/test3.py
Contents conflict in etl/lib/demo/test4.py
Contents conflict in etl/lib/demo/test5.py
Contents conflict in etl/lib/demo/test_server.py
Contents conflict in etl/lib/demo/test_unique.py
Contents conflict in etl/lib/demo/test_valid.py
Contents conflict in etl/lib/demo/vcard_openobject.py
Contents conflict in etl/lib/demo/vcard_read.py
Conflict: can't delete etl/lib/demo/xml_test because it is not empty.  Not deleting.
Conflict because etl/lib/demo/xml_test is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/demo/xml_test/dicttoxml.py
Contents conflict in etl/lib/demo/xml_test/xmltodict.py
Contents conflict in etl/lib/demo/xmlrpc_in_block_example.py
Contents conflict in etl/lib/demo/xmlrpc_in_example.py
Contents conflict in etl/lib/demo/xmlrpc_out_block_example.py
Contents conflict in etl/lib/demo/xmlrpc_out_example.py
Contents conflict in etl/lib/demo/xmlrpcserver_openobject.py
Conflict: can't delete etl/lib/etl because it is not empty.  Not deleting.
Conflict because etl/lib/etl is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete etl/lib/etl/component because it is not empty.  Not deleting.
Conflict because etl/lib/etl/component is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/etl/component/component.py
Conflict: can't delete etl/lib/etl/component/control because it is not empty.  Not deleting.
Conflict because etl/lib/etl/component/control is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/etl/component/control/__init__.py
Conflict: can't delete etl/lib/etl/component/input because it is not empty.  Not deleting.
Conflict because etl/lib/etl/component/input is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/etl/component/input/__init__.py
Conflict: can't delete etl/lib/etl/component/output because it is not empty.  Not deleting.
Conflict because etl/lib/etl/component/output is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/etl/component/output/openobject_out.py
Contents conflict in etl/lib/etl/component/output/openobject_out_write.py
Conflict: can't delete etl/lib/etl/component/transform because it is not empty.  Not deleting.
Conflict because etl/lib/etl/component/transform is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/etl/component/transform/__init__.py
Contents conflict in etl/lib/etl/component/transform/data_exist.py
Contents conflict in etl/lib/etl/component/transform/logger.py
Conflict: can't delete etl/lib/etl/connector because it is not empty.  Not deleting.
Conflict because etl/lib/etl/connector is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl/lib/etl/connector/openobject_connector.py
Contents conflict in etl/lib/etl/connector/sql_connector.py
Contents conflict in etl/lib/etl/job.py
Contents conflict in etl/lib/etl/logger.py
Contents conflict in etl/lib/etl/transition.py
Conflict: can't delete etl_interface because it is not empty.  Not deleting.
Conflict because etl_interface is not versioned, but has versioned children.  Versioned directory.
Contents conflict in etl_interface/etl_interface.py
Contents conflict in etl_interface/etl_interface_demo.xml
Conflict: can't delete event_certificate because it is not empty.  Not deleting.
Conflict because event_certificate is not versioned, but has versioned children.  Versioned directory.
Contents conflict in event_certificate/__init__.py
Contents conflict in event_certificate/__terp__.py
Contents conflict in event_certificate/event_certificate.py
Conflict: can't delete event_certificate/report because it is not empty.  Not deleting.
Conflict because event_certificate/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in event_certificate/report/__init__.py
Contents conflict in event_certificate/report/report_certificate.py
Contents conflict in event_certificate/report/rml_parse.py
Conflict: can't delete fashion because it is not empty.  Not deleting.
Conflict because fashion is not versioned, but has versioned children.  Versioned directory.
Contents conflict in fashion/__init__.py
Contents conflict in fashion/__terp__.py
Contents conflict in fashion/custom.py
Contents conflict in fashion/picture.py
Conflict: can't delete fashion/wizard because it is not empty.  Not deleting.
Conflict because fashion/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in fashion/wizard/__init__.py
Contents conflict in fashion/wizard/fashion_help_wizard.py
Conflict: can't delete flagey because it is not empty.  Not deleting.
Conflict because flagey is not versioned, but has versioned children.  Versioned directory.
Contents conflict in flagey/__init__.py
Contents conflict in flagey/__terp__.py
Conflict: can't delete fleet_maintenance because it is not empty.  Not deleting.
Conflict because fleet_maintenance is not versioned, but has versioned children.  Versioned directory.
Contents conflict in fleet_maintenance/__init__.py
Contents conflict in fleet_maintenance/__terp__.py
Contents conflict in fleet_maintenance/crm.py
Contents conflict in fleet_maintenance/invoice.py
Contents conflict in fleet_maintenance/partner.py
Contents conflict in fleet_maintenance/product.py
Contents conflict in fleet_maintenance/sale.py
Contents conflict in fleet_maintenance/stock.py
Conflict: can't delete game_scenario because it is not empty.  Not deleting.
Conflict because game_scenario is not versioned, but has versioned children.  Versioned directory.
Contents conflict in game_scenario/__init__.py
Contents conflict in game_scenario/__terp__.py
Contents conflict in game_scenario/game_scenario.py
Conflict: can't delete gnucash because it is not empty.  Not deleting.
Conflict because gnucash is not versioned, but has versioned children.  Versioned directory.
Contents conflict in gnucash/gnccontent.py
Contents conflict in gnucash/gnucash_wizard.py
Conflict: can't delete google_blogger because it is not empty.  Not deleting.
Conflict because google_blogger is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_blogger/__init__.py
Contents conflict in google_blogger/__terp__.py
Contents conflict in google_blogger/google_blogger.py
Contents conflict in google_blogger/google_blogger_wizard.xml
Conflict: can't delete google_blogger/wizard because it is not empty.  Not deleting.
Conflict because google_blogger/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_blogger/wizard/__init__.py
Contents conflict in google_blogger/wizard/create_blog_tasks.py
Conflict: can't delete google_calendar because it is not empty.  Not deleting.
Conflict because google_calendar is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_calendar/__init__.py
Contents conflict in google_calendar/__terp__.py
Contents conflict in google_calendar/google_calendar.py
Contents conflict in google_calendar/google_calendar_view.xml
Contents conflict in google_calendar/google_calendar_wizard.xml
Conflict: can't delete google_calendar/wizard because it is not empty.  Not deleting.
Conflict because google_calendar/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_calendar/wizard/__init__.py
Contents conflict in google_calendar/wizard/synchronize_events.py
Conflict: can't delete google_earth because it is not empty.  Not deleting.
Conflict because google_earth is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_earth/__init__.py
Contents conflict in google_earth/__terp__.py
Conflict: can't delete google_earth/document because it is not empty.  Not deleting.
Conflict because google_earth/document is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_earth/google_earth.py
Conflict: can't delete google_earth/wizard because it is not empty.  Not deleting.
Conflict because google_earth/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_earth/wizard/__init__.py
Contents conflict in google_earth/wizard/google_map_layer.py
Contents conflict in google_earth/wizard/google_map_open.py
Contents conflict in google_earth/wizard/google_map_turnover.py
Contents conflict in google_earth/wizard/google_route.py
Contents conflict in google_earth/wizard/goolge_network_link.py
Conflict: can't delete google_translate because it is not empty.  Not deleting.
Conflict because google_translate is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_translate/__init__.py
Contents conflict in google_translate/__terp__.py
Contents conflict in google_translate/google_translate.py
Conflict: can't delete google_translate/wizard because it is not empty.  Not deleting.
Conflict because google_translate/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in google_translate/wizard/__init__.py
Contents conflict in google_translate/wizard/term_translate.py
Conflict: can't delete health because it is not empty.  Not deleting.
Conflict because health is not versioned, but has versioned children.  Versioned directory.
Contents conflict in health/__terp__.py
Contents conflict in health/health.py
Conflict: can't delete health/report because it is not empty.  Not deleting.
Conflict because health/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in health/report/mouvementsemestriel.py
Conflict: can't delete hotel because it is not empty.  Not deleting.
Conflict because hotel is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel/__init__.py
Contents conflict in hotel/__terp__.py
Contents conflict in hotel/hotel.py
Conflict: can't delete hotel/report because it is not empty.  Not deleting.
Conflict because hotel/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel/report/__init__.py
Contents conflict in hotel/report/hotel_report.py
Conflict: can't delete hotel/wizard because it is not empty.  Not deleting.
Conflict because hotel/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel/wizard/__init__.py
Contents conflict in hotel/wizard/hotel_wizard.py
Conflict: can't delete hotel_housekeeping because it is not empty.  Not deleting.
Conflict because hotel_housekeeping is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_housekeeping/__init__.py
Contents conflict in hotel_housekeeping/__terp__.py
Contents conflict in hotel_housekeeping/hotel_housekeeping.py
Conflict: can't delete hotel_housekeeping/report because it is not empty.  Not deleting.
Conflict because hotel_housekeeping/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_housekeeping/report/__init__.py
Contents conflict in hotel_housekeeping/report/housekeeping_report.py
Conflict: can't delete hotel_housekeeping/wizard because it is not empty.  Not deleting.
Conflict because hotel_housekeeping/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_housekeeping/wizard/__init__.py
Contents conflict in hotel_housekeeping/wizard/housekeeping_wizard.py
Conflict: can't delete hotel_reservation because it is not empty.  Not deleting.
Conflict because hotel_reservation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_reservation/__init__.py
Contents conflict in hotel_reservation/__terp__.py
Contents conflict in hotel_reservation/hotel_reservation.py
Conflict: can't delete hotel_reservation/report because it is not empty.  Not deleting.
Conflict because hotel_reservation/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_reservation/report/__init__.py
Contents conflict in hotel_reservation/report/hotel_reservation_report.py
Conflict: can't delete hotel_reservation/wizard because it is not empty.  Not deleting.
Conflict because hotel_reservation/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_reservation/wizard/__init__.py
Contents conflict in hotel_reservation/wizard/hotel_reservation_wizard.py
Conflict: can't delete hotel_restaurant because it is not empty.  Not deleting.
Conflict because hotel_restaurant is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_restaurant/__init__.py
Contents conflict in hotel_restaurant/__terp__.py
Contents conflict in hotel_restaurant/hotel_restaurant.py
Contents conflict in hotel_restaurant/hotel_restaurant_view.xml
Conflict: can't delete hotel_restaurant/report because it is not empty.  Not deleting.
Conflict because hotel_restaurant/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_restaurant/report/__init__.py
Contents conflict in hotel_restaurant/report/hotel_restaurant_report.py
Conflict: can't delete hotel_restaurant/wizard because it is not empty.  Not deleting.
Conflict because hotel_restaurant/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hotel_restaurant/wizard/__init__.py
Contents conflict in hotel_restaurant/wizard/hotel_restaurant_wizard.py
Conflict: can't delete hr_contract_available because it is not empty.  Not deleting.
Conflict because hr_contract_available is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_contract_available/__init__.py
Contents conflict in hr_contract_available/__terp__.py
Contents conflict in hr_contract_available/hr_contract_available.py
Contents conflict in hr_contract_available/hr_contract_available_view.xml
Conflict: can't delete hr_contract_available/security because it is not empty.  Not deleting.
Conflict because hr_contract_available/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_contract_available/security/ir.model.access.csv
Conflict: can't delete hr_contract_timesheet because it is not empty.  Not deleting.
Conflict because hr_contract_timesheet is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_contract_timesheet/__init__.py
Contents conflict in hr_contract_timesheet/__terp__.py
Contents conflict in hr_contract_timesheet/hr_contract_timesheet.py
Conflict: can't delete hr_holidays_cci because it is not empty.  Not deleting.
Conflict because hr_holidays_cci is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_cci/__init__.py
Contents conflict in hr_holidays_cci/__terp__.py
Conflict: can't delete hr_holidays_cci/report because it is not empty.  Not deleting.
Conflict because hr_holidays_cci/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_cci/report/__init__.py
Contents conflict in hr_holidays_cci/report/holidays_summary_report.py
Conflict: can't delete hr_holidays_cci/wizard because it is not empty.  Not deleting.
Conflict because hr_holidays_cci/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_cci/wizard/__init__.py
Contents conflict in hr_holidays_cci/wizard/holidays_summary.py
Conflict: can't delete hr_holidays_evaluation because it is not empty.  Not deleting.
Conflict because hr_holidays_evaluation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_evaluation/__init__.py
Contents conflict in hr_holidays_evaluation/__terp__.py
Contents conflict in hr_holidays_evaluation/hr_holidays_evaluation.py
Contents conflict in hr_holidays_evaluation/hr_holidays_evaluation_view.xml
Conflict: can't delete hr_holidays_evaluation/security because it is not empty.  Not deleting.
Conflict because hr_holidays_evaluation/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_evaluation/security/ir.model.access.csv
Conflict: can't delete hr_holidays_request because it is not empty.  Not deleting.
Conflict because hr_holidays_request is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_request/__init__.py
Contents conflict in hr_holidays_request/__terp__.py
Contents conflict in hr_holidays_request/hr_holidays_request.py
Contents conflict in hr_holidays_request/hr_holidays_request_view.xml
Contents conflict in hr_holidays_request/hr_workflow.xml
Conflict: can't delete hr_holidays_request/report because it is not empty.  Not deleting.
Conflict because hr_holidays_request/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_request/report/__init__.py
Contents conflict in hr_holidays_request/report/hr_holiday_report.py
Contents conflict in hr_holidays_request/report/hr_holiday_report_form.py
Conflict: can't delete hr_holidays_request/security because it is not empty.  Not deleting.
Conflict because hr_holidays_request/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_request/security/ir.model.access.csv
Conflict: can't delete hr_holidays_request/wizard because it is not empty.  Not deleting.
Conflict because hr_holidays_request/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_holidays_request/wizard/__init__.py
Contents conflict in hr_holidays_request/wizard/hr_holiday.py
Conflict: can't delete hr_performance because it is not empty.  Not deleting.
Conflict because hr_performance is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_performance/__init__.py
Contents conflict in hr_performance/__terp__.py
Contents conflict in hr_performance/hr_performance.py
Conflict: can't delete hr_performance/report because it is not empty.  Not deleting.
Conflict because hr_performance/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_performance/report/__init__.py
Contents conflict in hr_performance/report/hr_performance_report.py
Conflict: can't delete hr_performance/security because it is not empty.  Not deleting.
Conflict because hr_performance/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_performance/security/ir.model.access.csv
Conflict: can't delete hr_skill because it is not empty.  Not deleting.
Conflict because hr_skill is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_skill/__init__.py
Contents conflict in hr_skill/__terp__.py
Contents conflict in hr_skill/hr_skill.py
Contents conflict in hr_skill/hr_skill_view.xml
Contents conflict in hr_skill/hrskill.py
Conflict: can't delete hr_skill/report because it is not empty.  Not deleting.
Conflict because hr_skill/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_skill/report/__init__.py
Contents conflict in hr_skill/report/employeereport.py
Contents conflict in hr_skill/report/langreport.py
Contents conflict in hr_skill/report/skillreport.py
Conflict: can't delete hr_skill/security because it is not empty.  Not deleting.
Conflict because hr_skill/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_skill/security/ir.model.access.csv
Conflict: can't delete hr_skill/wizard because it is not empty.  Not deleting.
Conflict because hr_skill/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_skill/wizard/__init__.py
Contents conflict in hr_skill/wizard/datewise.py
Contents conflict in hr_skill/wizard/lang_wiz.py
Contents conflict in hr_skill/wizard/skill.py
Conflict: can't delete hr_timesheet_ical because it is not empty.  Not deleting.
Conflict because hr_timesheet_ical is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_timesheet_ical/__init__.py
Contents conflict in hr_timesheet_ical/__terp__.py
Conflict: can't delete hr_timesheet_ical/wizard because it is not empty.  Not deleting.
Conflict because hr_timesheet_ical/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in hr_timesheet_ical/wizard/__init__.py
Contents conflict in hr_timesheet_ical/wizard/urllib2.py
Contents conflict in hr_timesheet_ical/wizard/wizard_ical.py
Conflict: can't delete huissier because it is not empty.  Not deleting.
Conflict because huissier is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete huissier/barcode because it is not empty.  Not deleting.
Conflict because huissier/barcode is not versioned, but has versioned children.  Versioned directory.
Contents conflict in huissier/barcode/code128.py
Contents conflict in huissier/barcode/common.py
Contents conflict in huissier/barcode/test.py
Conflict: can't delete import_export because it is not empty.  Not deleting.
Conflict because import_export is not versioned, but has versioned children.  Versioned directory.
Contents conflict in import_export/__init__.py
Contents conflict in import_export/__terp__.py
Contents conflict in import_export/partner.py
Contents conflict in import_export/product.py
Contents conflict in import_export/purchase.py
Contents conflict in import_export/sale.py
Conflict: can't delete invoice_multi_currency because it is not empty.  Not deleting.
Conflict because invoice_multi_currency is not versioned, but has versioned children.  Versioned directory.
Contents conflict in invoice_multi_currency/__init__.py
Contents conflict in invoice_multi_currency/__terp__.py
Contents conflict in invoice_multi_currency/invoice.py
Conflict: can't delete invoice_multi_currency/wizard because it is not empty.  Not deleting.
Conflict because invoice_multi_currency/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in invoice_multi_currency/wizard/__init__.py
Contents conflict in invoice_multi_currency/wizard/wizard_change_currency.py
Conflict: can't delete invoice_sequence because it is not empty.  Not deleting.
Conflict because invoice_sequence is not versioned, but has versioned children.  Versioned directory.
Contents conflict in invoice_sequence/__init__.py
Contents conflict in invoice_sequence/__terp__.py
Contents conflict in invoice_sequence/invoice.py
Conflict: can't delete l10n_ca-qc because it is not empty.  Not deleting.
Conflict because l10n_ca-qc is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_ca-qc/__init__.py
Contents conflict in l10n_ca-qc/__terp__.py
Contents conflict in l10n_ca-qc/account_pc_canada.xml
Conflict: can't delete l10n_ch_bank because it is not empty.  Not deleting.
Path conflict: l10n_ch_bank / <deleted>
Conflict because l10n_ch_bank is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_ch_bank/__init__.py
Contents conflict in l10n_ch_bank/__openerp__.py
Conflict: can't delete l10n_ch_vat_brut because it is not empty.  Not deleting.
Conflict because l10n_ch_vat_brut is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_ch_vat_brut/__init__.py
Contents conflict in l10n_ch_vat_brut/__terp__.py
Conflict: can't delete l10n_ch_vat_forfait because it is not empty.  Not deleting.
Conflict because l10n_ch_vat_forfait is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_ch_vat_forfait/__init__.py
Contents conflict in l10n_ch_vat_forfait/__terp__.py
Conflict: can't delete l10n_ch_vat_net because it is not empty.  Not deleting.
Conflict because l10n_ch_vat_net is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_ch_vat_net/__init__.py
Contents conflict in l10n_ch_vat_net/__terp__.py
Conflict: can't delete l10n_chart_at because it is not empty.  Not deleting.
Conflict because l10n_chart_at is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_at/__init__.py
Contents conflict in l10n_chart_at/__terp__.py
Conflict: can't delete l10n_chart_au because it is not empty.  Not deleting.
Conflict because l10n_chart_au is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_au/__init__.py
Contents conflict in l10n_chart_au/__terp__.py
Conflict: can't delete l10n_chart_be_frnl because it is not empty.  Not deleting.
Conflict because l10n_chart_be_frnl is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_be_frnl/__init__.py
Contents conflict in l10n_chart_be_frnl/__terp__.py
Conflict: can't delete l10n_chart_br because it is not empty.  Not deleting.
Conflict because l10n_chart_br is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_br/__init__.py
Contents conflict in l10n_chart_br/__terp__.py
Conflict: can't delete l10n_chart_ca_en because it is not empty.  Not deleting.
Conflict because l10n_chart_ca_en is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_ca_en/__init__.py
Contents conflict in l10n_chart_ca_en/__terp__.py
Conflict: can't delete l10n_chart_ca_fr because it is not empty.  Not deleting.
Conflict because l10n_chart_ca_fr is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_ca_fr/__init__.py
Contents conflict in l10n_chart_ca_fr/__terp__.py
Conflict: can't delete l10n_chart_ch_german because it is not empty.  Not deleting.
Conflict because l10n_chart_ch_german is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_ch_german/__init__.py
Contents conflict in l10n_chart_ch_german/__terp__.py
Conflict: can't delete l10n_chart_cn because it is not empty.  Not deleting.
Conflict because l10n_chart_cn is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_cn/__init__.py
Contents conflict in l10n_chart_cn/__terp__.py
Conflict: can't delete l10n_chart_cn_traditional because it is not empty.  Not deleting.
Conflict because l10n_chart_cn_traditional is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_cn_traditional/__init__.py
Contents conflict in l10n_chart_cn_traditional/__terp__.py
Conflict: can't delete l10n_chart_co because it is not empty.  Not deleting.
Conflict because l10n_chart_co is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_co/__init__.py
Contents conflict in l10n_chart_co/__terp__.py
Conflict: can't delete l10n_chart_cz because it is not empty.  Not deleting.
Conflict because l10n_chart_cz is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_cz/__init__.py
Contents conflict in l10n_chart_cz/__terp__.py
Conflict: can't delete l10n_chart_da because it is not empty.  Not deleting.
Conflict because l10n_chart_da is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_da/__init__.py
Contents conflict in l10n_chart_da/__terp__.py
Conflict: can't delete l10n_chart_de_skr03 because it is not empty.  Not deleting.
Conflict because l10n_chart_de_skr03 is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_de_skr03/__init__.py
Contents conflict in l10n_chart_de_skr03/__terp__.py
Conflict: can't delete l10n_chart_hu because it is not empty.  Not deleting.
Conflict because l10n_chart_hu is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_hu/__init__.py
Contents conflict in l10n_chart_hu/__terp__.py
Conflict: can't delete l10n_chart_in because it is not empty.  Not deleting.
Conflict because l10n_chart_in is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_in/__terp__.py
Contents conflict in l10n_chart_in/account_chart.xml
Conflict: can't delete l10n_chart_it because it is not empty.  Not deleting.
Conflict because l10n_chart_it is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_it/__init__.py
Contents conflict in l10n_chart_it/__terp__.py
Conflict: can't delete l10n_chart_it_cc2424 because it is not empty.  Not deleting.
Conflict because l10n_chart_it_cc2424 is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_it_cc2424/__init__.py
Contents conflict in l10n_chart_it_cc2424/__terp__.py
Conflict: can't delete l10n_chart_lv because it is not empty.  Not deleting.
Conflict because l10n_chart_lv is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_lv/__init__.py
Contents conflict in l10n_chart_lv/__terp__.py
Conflict: can't delete l10n_chart_nl because it is not empty.  Not deleting.
Conflict because l10n_chart_nl is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_nl/__init__.py
Contents conflict in l10n_chart_nl/__terp__.py
Conflict: can't delete l10n_chart_nl_standard because it is not empty.  Not deleting.
Conflict because l10n_chart_nl_standard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_nl_standard/__init__.py
Contents conflict in l10n_chart_nl_standard/__terp__.py
Conflict: can't delete l10n_chart_no because it is not empty.  Not deleting.
Conflict because l10n_chart_no is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_no/__init__.py
Contents conflict in l10n_chart_no/__terp__.py
Conflict: can't delete l10n_chart_pa because it is not empty.  Not deleting.
Conflict because l10n_chart_pa is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_pa/__init__.py
Contents conflict in l10n_chart_pa/__terp__.py
Conflict: can't delete l10n_chart_pl because it is not empty.  Not deleting.
Conflict because l10n_chart_pl is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_pl/__init__.py
Contents conflict in l10n_chart_pl/__terp__.py
Contents conflict in l10n_chart_pl/account_chart.xml
Contents conflict in l10n_chart_pl/account_tax.xml
Contents conflict in l10n_chart_pl/account_tax_code.xml
Conflict: can't delete l10n_chart_se because it is not empty.  Not deleting.
Conflict because l10n_chart_se is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_se/__init__.py
Contents conflict in l10n_chart_se/__terp__.py
Conflict: can't delete l10n_chart_se_church because it is not empty.  Not deleting.
Conflict because l10n_chart_se_church is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_se_church/__init__.py
Contents conflict in l10n_chart_se_church/__terp__.py
Conflict: can't delete l10n_chart_se_food because it is not empty.  Not deleting.
Conflict because l10n_chart_se_food is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_se_food/__init__.py
Contents conflict in l10n_chart_se_food/__terp__.py
Conflict: can't delete l10n_chart_uk because it is not empty.  Not deleting.
Conflict because l10n_chart_uk is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_uk/__init__.py
Contents conflict in l10n_chart_uk/__terp__.py
Conflict: can't delete l10n_chart_us_general because it is not empty.  Not deleting.
Conflict because l10n_chart_us_general is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_us_general/__init__.py
Contents conflict in l10n_chart_us_general/__terp__.py
Contents conflict in l10n_chart_us_general/account_chart.xml
Contents conflict in l10n_chart_us_general/account_tax.xml
Contents conflict in l10n_chart_us_general/account_tax_code.xml
Conflict: can't delete l10n_chart_us_manufacturing because it is not empty.  Not deleting.
Conflict because l10n_chart_us_manufacturing is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_us_manufacturing/__init__.py
Contents conflict in l10n_chart_us_manufacturing/__terp__.py
Contents conflict in l10n_chart_us_manufacturing/account_chart.xml
Contents conflict in l10n_chart_us_manufacturing/account_tax.xml
Contents conflict in l10n_chart_us_manufacturing/account_tax_code.xml
Contents conflict in l10n_chart_us_manufacturing/l10n_us_wizard.xml
Conflict: can't delete l10n_chart_us_service because it is not empty.  Not deleting.
Conflict because l10n_chart_us_service is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_us_service/__init__.py
Contents conflict in l10n_chart_us_service/__terp__.py
Contents conflict in l10n_chart_us_service/account_chart.xml
Contents conflict in l10n_chart_us_service/account_tax.xml
Contents conflict in l10n_chart_us_service/account_tax_code.xml
Contents conflict in l10n_chart_us_service/l10n_us_wizard.xml
Conflict: can't delete l10n_chart_us_ucoa because it is not empty.  Not deleting.
Conflict because l10n_chart_us_ucoa is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_us_ucoa/__init__.py
Contents conflict in l10n_chart_us_ucoa/__terp__.py
Contents conflict in l10n_chart_us_ucoa/account_chart.xml
Contents conflict in l10n_chart_us_ucoa/account_tax.xml
Contents conflict in l10n_chart_us_ucoa/account_tax_code.xml
Conflict: can't delete l10n_chart_us_ucoa_ez because it is not empty.  Not deleting.
Conflict because l10n_chart_us_ucoa_ez is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_us_ucoa_ez/__init__.py
Contents conflict in l10n_chart_us_ucoa_ez/__terp__.py
Contents conflict in l10n_chart_us_ucoa_ez/account_chart.xml
Contents conflict in l10n_chart_us_ucoa_ez/account_tax.xml
Contents conflict in l10n_chart_us_ucoa_ez/account_tax_code.xml
Conflict: can't delete l10n_chart_ve because it is not empty.  Not deleting.
Conflict because l10n_chart_ve is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_chart_ve/__init__.py
Contents conflict in l10n_chart_ve/__terp__.py
Conflict: can't delete l10n_fr_account_generation because it is not empty.  Not deleting.
Conflict because l10n_fr_account_generation is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete l10n_fr_account_generation/i18n because it is not empty.  Not deleting.
Conflict because l10n_fr_account_generation/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_fr_account_generation/partner.py
Conflict: can't delete l10n_fr_export because it is not empty.  Not deleting.
Conflict because l10n_fr_export is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete l10n_fr_export/i18n because it is not empty.  Not deleting.
Conflict because l10n_fr_export/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete l10n_fr_pcg because it is not empty.  Not deleting.
Conflict because l10n_fr_pcg is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete l10n_fr_tva_franchise because it is not empty.  Not deleting.
Conflict because l10n_fr_tva_franchise is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete l10n_fr_tva_reel because it is not empty.  Not deleting.
Conflict because l10n_fr_tva_reel is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete l10n_simple because it is not empty.  Not deleting.
Conflict because l10n_simple is not versioned, but has versioned children.  Versioned directory.
Contents conflict in l10n_simple/__init__.py
Contents conflict in l10n_simple/__terp__.py
Contents conflict in l10n_simple/tax_configure_wiz.py
Conflict: can't delete label because it is not empty.  Not deleting.
Conflict because label is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete label/i18n because it is not empty.  Not deleting.
Conflict because label/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete labo_analysis because it is not empty.  Not deleting.
Conflict because labo_analysis is not versioned, but has versioned children.  Versioned directory.
Contents conflict in labo_analysis/__terp__.py
Contents conflict in labo_analysis/labo_analysis.py
Conflict: can't delete labo_analysis/report because it is not empty.  Not deleting.
Conflict because labo_analysis/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in labo_analysis/report/__init__.py
Contents conflict in labo_analysis/report/invoice.py
Contents conflict in labo_analysis/report/labo_request_report.py
Contents conflict in labo_analysis/report/report_dna.py
Contents conflict in labo_analysis/report/report_followsheet_of_sample.py
Contents conflict in labo_analysis/report/report_scid_2007_0276.py
Contents conflict in labo_analysis/report/report_scrapie_2007.py
Contents conflict in labo_analysis/report/report_setup.py
Contents conflict in labo_analysis/report/report_stress_2007_0649.py
Path conflict: labo_analysis/table_conversion_empdog_chiffre_lettre.csv / <deleted>
Conflict: can't delete labo_analysis/wizard because it is not empty.  Not deleting.
Conflict because labo_analysis/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in labo_analysis/wizard/__init__.py
Contents conflict in labo_analysis/wizard/wizard_allsetting.py
Contents conflict in labo_analysis/wizard/wizard_analysiis_import_xls.py
Contents conflict in labo_analysis/wizard/wizard_import_resdog.py
Contents conflict in labo_analysis/wizard/wizard_repeat_line.py
Contents conflict in labo_analysis/wizard/wizard_setup.py
Conflict: can't delete labo_stock because it is not empty.  Not deleting.
Conflict because labo_stock is not versioned, but has versioned children.  Versioned directory.
Contents conflict in labo_stock/__terp__.py
Conflict: can't delete labo_stock/report because it is not empty.  Not deleting.
Conflict because labo_stock/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in labo_stock/report/__init__.py
Contents conflict in labo_stock/report/report_composition_mix.py
Conflict: can't delete labo_stock/wizard because it is not empty.  Not deleting.
Conflict because labo_stock/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in labo_stock/wizard/wizard_invoice_article.py
Conflict: can't delete library because it is not empty.  Not deleting.
Conflict because library is not versioned, but has versioned children.  Versioned directory.
Contents conflict in library/__init__.py
Contents conflict in library/__terp__.py
Contents conflict in library/account.py
Conflict: can't delete library/i18n because it is not empty.  Not deleting.
Conflict because library/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in library/i18n/fr_FR.po
Contents conflict in library/library.py
Contents conflict in library/library_data.xml
Contents conflict in library/library_editor_supplier.py
Contents conflict in library/library_view.xml
Contents conflict in library/library_wizard.xml
Contents conflict in library/mrp.py
Contents conflict in library/product.py
Contents conflict in library/purchase.py
Contents conflict in library/sale.py
Contents conflict in library/stock.py
Conflict: can't delete library/wizard because it is not empty.  Not deleting.
Conflict because library/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in library/wizard/__init__.py
Contents conflict in library/wizard/wizard_update_prices.py
Conflict: can't delete loan because it is not empty.  Not deleting.
Conflict because loan is not versioned, but has versioned children.  Versioned directory.
Contents conflict in loan/__init__.py
Contents conflict in loan/__terp__.py
Contents conflict in loan/cheque.py
Contents conflict in loan/installment.py
Contents conflict in loan/loan.py
Contents conflict in loan/loan_proof.py
Contents conflict in loan/loantype.py
Conflict: can't delete loan/report because it is not empty.  Not deleting.
Conflict because loan/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in loan/report/__init__.py
Contents conflict in loan/report/loan_details.py
Contents conflict in loan/report/loan_paper.py
Contents conflict in loan/report/partner_loan.py
Conflict: can't delete loan/wizard because it is not empty.  Not deleting.
Conflict because loan/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in loan/wizard/__init__.py
Contents conflict in loan/wizard/wizard_cheque_state_process.py
Contents conflict in loan/wizard/wizard_create_account.py
Contents conflict in loan/wizard/wizard_partner_loan_report.py
Conflict: can't delete magento_openerp_synchro because it is not empty.  Not deleting.
Conflict because magento_openerp_synchro is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete magento_openerp_synchro/i18n because it is not empty.  Not deleting.
Conflict because magento_openerp_synchro/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in magento_openerp_synchro/magento.py
Contents conflict in magento_openerp_synchro/magento_utils.py
Contents conflict in magento_openerp_synchro/product.py
Conflict: can't delete magento_openerp_synchro/wizard because it is not empty.  Not deleting.
Conflict because magento_openerp_synchro/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in magento_openerp_synchro/wizard/__init__.py
Contents conflict in magento_openerp_synchro/wizard/magento_category_synchronize.py
Contents conflict in magento_openerp_synchro/wizard/magento_product_synchronize.py
Contents conflict in magento_openerp_synchro/wizard/magento_so_correct.py
Contents conflict in magento_openerp_synchro/wizard/magento_so_import.py
Contents conflict in magento_openerp_synchro/wizard/magento_so_update.py
Conflict: can't delete maintenance_editor because it is not empty.  Not deleting.
Conflict because maintenance_editor is not versioned, but has versioned children.  Versioned directory.
Contents conflict in maintenance_editor/__terp__.py
Contents conflict in maintenance_editor/maintenance_editor.py
Contents conflict in maintenance_editor/maintenance_editor_view.xml
Contents conflict in maintenance_editor/maintenance_report.xml
Conflict: can't delete maintenance_editor/report because it is not empty.  Not deleting.
Conflict because maintenance_editor/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in maintenance_editor/report/__init__.py
Conflict: can't delete md_hr_contract because it is not empty.  Not deleting.
Conflict because md_hr_contract is not versioned, but has versioned children.  Versioned directory.
Contents conflict in md_hr_contract/__init__.py
Contents conflict in md_hr_contract/__terp__.py
Contents conflict in md_hr_contract/md_hr_contract.py
Contents conflict in md_hr_contract/md_hr_contract_view.xml
Conflict: can't delete md_hr_contract/security because it is not empty.  Not deleting.
Conflict because md_hr_contract/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in md_hr_contract/security/ir.model.access.csv
Conflict: can't delete md_hr_course because it is not empty.  Not deleting.
Conflict because md_hr_course is not versioned, but has versioned children.  Versioned directory.
Contents conflict in md_hr_course/__init__.py
Contents conflict in md_hr_course/__terp__.py
Contents conflict in md_hr_course/md_hr_course.py
Conflict: can't delete md_hr_course/security because it is not empty.  Not deleting.
Conflict because md_hr_course/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in md_hr_course/security/ir.model.access.csv
Conflict: can't delete md_hr_employee because it is not empty.  Not deleting.
Conflict because md_hr_employee is not versioned, but has versioned children.  Versioned directory.
Contents conflict in md_hr_employee/__init__.py
Contents conflict in md_hr_employee/__terp__.py
Contents conflict in md_hr_employee/md_hr_employee.py
Contents conflict in md_hr_employee/md_hr_employee_data.xml
Conflict: can't delete membership_card because it is not empty.  Not deleting.
Conflict because membership_card is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete membership_card/i18n because it is not empty.  Not deleting.
Conflict because membership_card/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete merge_picking because it is not empty.  Not deleting.
Conflict because merge_picking is not versioned, but has versioned children.  Versioned directory.
Contents conflict in merge_picking/__init__.py
Contents conflict in merge_picking/__terp__.py
Conflict: can't delete merge_picking/wizard because it is not empty.  Not deleting.
Conflict because merge_picking/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in merge_picking/wizard/__init__.py
Contents conflict in merge_picking/wizard/merge_picking.py
Conflict: can't delete mrp_bom_customization because it is not empty.  Not deleting.
Conflict because mrp_bom_customization is not versioned, but has versioned children.  Versioned directory.
Contents conflict in mrp_bom_customization/configurator_wizard.py
Conflict: can't delete mrp_bom_customization/i18n because it is not empty.  Not deleting.
Conflict because mrp_bom_customization/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in mrp_bom_customization/stock.py
Conflict: can't delete mrp_prodlot_autosplit because it is not empty.  Not deleting.
Conflict because mrp_prodlot_autosplit is not versioned, but has versioned children.  Versioned directory.
Contents conflict in mrp_prodlot_autosplit/__init__.py
Contents conflict in mrp_prodlot_autosplit/__terp__.py
Contents conflict in mrp_prodlot_autosplit/product.py
Contents conflict in mrp_prodlot_autosplit/stock.py
Conflict: can't delete mrp_production_report because it is not empty.  Not deleting.
Conflict because mrp_production_report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in mrp_production_report/__init__.py
Contents conflict in mrp_production_report/__terp__.py
Contents conflict in mrp_production_report/mrp.py
Conflict: can't delete mrp_production_report/report because it is not empty.  Not deleting.
Conflict because mrp_production_report/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in mrp_production_report/report/__init__.py
Contents conflict in mrp_production_report/report/order.py
Conflict: can't delete mrp_state because it is not empty.  Not deleting.
Conflict because mrp_state is not versioned, but has versioned children.  Versioned directory.
Contents conflict in mrp_state/__init__.py
Contents conflict in mrp_state/__terp__.py
Contents conflict in mrp_state/mrp.py
Conflict: can't delete multi_company_account because it is not empty.  Not deleting.
Conflict because multi_company_account is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_account/__init__.py
Contents conflict in multi_company_account/__terp__.py
Conflict: can't delete multi_company_account/i18n because it is not empty.  Not deleting.
Conflict because multi_company_account/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_account/i18n/pt_BR.po
Contents conflict in multi_company_account/i18n/zh_CN.po
Contents conflict in multi_company_account/i18n/zh_TW.po
Contents conflict in multi_company_account/multi_company_account.py
Conflict: can't delete multi_company_account/wizard because it is not empty.  Not deleting.
Conflict because multi_company_account/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_account/wizard/__init__.py
Contents conflict in multi_company_account/wizard/company_header_footer_setup.py
Contents conflict in multi_company_account/wizard/wizard_journal.py
Conflict: can't delete multi_company_currency because it is not empty.  Not deleting.
Conflict because multi_company_currency is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_currency/__init__.py
Contents conflict in multi_company_currency/__terp__.py
Contents conflict in multi_company_currency/multi_currency.py
Conflict: can't delete multi_company_hr_timesheet_sheet because it is not empty.  Not deleting.
Conflict because multi_company_hr_timesheet_sheet is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_hr_timesheet_sheet/__init__.py
Contents conflict in multi_company_hr_timesheet_sheet/__terp__.py
Contents conflict in multi_company_hr_timesheet_sheet/multi_company_hr_timesheet_sheet.py
Conflict: can't delete multi_company_product because it is not empty.  Not deleting.
Conflict because multi_company_product is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_product/__init__.py
Contents conflict in multi_company_product/__terp__.py
Contents conflict in multi_company_product/product.py
Conflict: can't delete multi_company_project because it is not empty.  Not deleting.
Conflict because multi_company_project is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_project/__init__.py
Contents conflict in multi_company_project/__terp__.py
Contents conflict in multi_company_project/multi_company_project.py
Conflict: can't delete multi_company_sequence because it is not empty.  Not deleting.
Conflict because multi_company_sequence is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_sequence/__init__.py
Contents conflict in multi_company_sequence/__terp__.py
Contents conflict in multi_company_sequence/multi_company_sequence.py
Conflict: can't delete multi_company_stock because it is not empty.  Not deleting.
Conflict because multi_company_stock is not versioned, but has versioned children.  Versioned directory.
Contents conflict in multi_company_stock/__init__.py
Contents conflict in multi_company_stock/__terp__.py
Contents conflict in multi_company_stock/multi_company_stock.py
Conflict: can't delete multilogin_portal because it is not empty.  Not deleting.
Conflict because multilogin_portal is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete network because it is not empty.  Not deleting.
Conflict because network is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete network/i18n because it is not empty.  Not deleting.
Conflict because network/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in network/i18n/network.pot
Contents conflict in network/network.py
Contents conflict in network/network_view.xml
Conflict: can't delete network/security because it is not empty.  Not deleting.
Conflict because network/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in network/security/ir.model.access.csv
Contents conflict in network/security/network_security.xml
Conflict: can't delete network_extension because it is not empty.  Not deleting.
Conflict because network_extension is not versioned, but has versioned children.  Versioned directory.
Contents conflict in network_extension/__init__.py
Conflict: can't delete network_extension/i18n because it is not empty.  Not deleting.
Conflict because network_extension/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in network_extension/i18n/network_extension.pot
Contents conflict in network_extension/network.py
Contents conflict in network_extension/network_protocol_data.xml
Contents conflict in network_extension/network_view.xml
Conflict: can't delete network_extension/security because it is not empty.  Not deleting.
Conflict because network_extension/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in network_extension/security/ir.model.access.csv
Conflict: can't delete olap because it is not empty.  Not deleting.
Conflict because olap is not versioned, but has versioned children.  Versioned directory.
Contents conflict in olap/__terp__.py
Conflict: can't delete olap/cube because it is not empty.  Not deleting.
Conflict because olap/cube is not versioned, but has versioned children.  Versioned directory.
Contents conflict in olap/cube/level.py
Contents conflict in olap/cube/warehouse.py
Conflict: can't delete olap_crm because it is not empty.  Not deleting.
Conflict because olap_crm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in olap_crm/__init__.py
Contents conflict in olap_crm/__terp__.py
Conflict: can't delete olap_extract because it is not empty.  Not deleting.
Conflict because olap_extract is not versioned, but has versioned children.  Versioned directory.
Contents conflict in olap_extract/__init__.py
Contents conflict in olap_extract/__terp__.py
Contents conflict in olap_extract/wizard_olap_extract.py
Conflict: can't delete olap_sale because it is not empty.  Not deleting.
Conflict because olap_sale is not versioned, but has versioned children.  Versioned directory.
Contents conflict in olap_sale/__init__.py
Contents conflict in olap_sale/__terp__.py
Conflict: can't delete openerp_dia because it is not empty.  Not deleting.
Path conflict: openerp_dia / <deleted>
Conflict because openerp_dia is not versioned, but has versioned children.  Versioned directory.
Contents conflict in openerp_dia/codegen_openerp.py
Conflict: can't delete partner_informations because it is not empty.  Not deleting.
Conflict because partner_informations is not versioned, but has versioned children.  Versioned directory.
Contents conflict in partner_informations/__init__.py
Contents conflict in partner_informations/__terp__.py
Conflict: can't delete partner_informations/i18n because it is not empty.  Not deleting.
Conflict because partner_informations/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in partner_informations/partner_informations.py
Conflict: can't delete partner_layout because it is not empty.  Not deleting.
Conflict because partner_layout is not versioned, but has versioned children.  Versioned directory.
Contents conflict in partner_layout/__init__.py
Contents conflict in partner_layout/__terp__.py
Contents conflict in partner_layout/partner_layout.py
Conflict: can't delete partner_ldap because it is not empty.  Not deleting.
Conflict because partner_ldap is not versioned, but has versioned children.  Versioned directory.
Contents conflict in partner_ldap/__init__.py
Contents conflict in partner_ldap/__terp__.py
Contents conflict in partner_ldap/partner.py
Conflict: can't delete partner_ldap/wizard because it is not empty.  Not deleting.
Conflict because partner_ldap/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in partner_ldap/wizard/__init__.py
Contents conflict in partner_ldap/wizard/synchronize.py
Conflict: can't delete partner_nace because it is not empty.  Not deleting.
Conflict because partner_nace is not versioned, but has versioned children.  Versioned directory.
Contents conflict in partner_nace/__init__.py
Contents conflict in partner_nace/__terp__.py
Conflict: can't delete partner_nace/i18n because it is not empty.  Not deleting.
Conflict because partner_nace/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete partner_spam because it is not empty.  Not deleting.
Conflict because partner_spam is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete partner_spam/i18n because it is not empty.  Not deleting.
Conflict because partner_spam/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete partner_spam/wizard because it is not empty.  Not deleting.
Conflict because partner_spam/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in partner_spam/wizard/wizard_spam.py
Conflict: can't delete personal_base because it is not empty.  Not deleting.
Conflict because personal_base is not versioned, but has versioned children.  Versioned directory.
Contents conflict in personal_base/account.py
Contents conflict in personal_base/personal_base.csv
Conflict: can't delete portal_account because it is not empty.  Not deleting.
Conflict because portal_account is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete portal_analytic because it is not empty.  Not deleting.
Conflict because portal_analytic is not versioned, but has versioned children.  Versioned directory.
Contents conflict in portal_analytic/__init__.py
Contents conflict in portal_analytic/portal_analytic_view.xml
Conflict: can't delete portal_analytic_package because it is not empty.  Not deleting.
Conflict because portal_analytic_package is not versioned, but has versioned children.  Versioned directory.
Contents conflict in portal_analytic_package/__terp__.py
Conflict: can't delete portal_project because it is not empty.  Not deleting.
Conflict because portal_project is not versioned, but has versioned children.  Versioned directory.
Contents conflict in portal_project/__terp__.py
Contents conflict in portal_project/portal_project.py
Contents conflict in portal_project/portal_project_data.xml
Contents conflict in portal_project/portal_project_view.xml
Conflict: can't delete portal_project/wizard because it is not empty.  Not deleting.
Conflict because portal_project/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in portal_project/wizard/wizard_check_section.py
Conflict: can't delete portal_sale because it is not empty.  Not deleting.
Conflict because portal_sale is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete portal_service because it is not empty.  Not deleting.
Conflict because portal_service is not versioned, but has versioned children.  Versioned directory.
Contents conflict in portal_service/__init__.py
Contents conflict in portal_service/scrum.py
Conflict: can't delete portal_service/wizard because it is not empty.  Not deleting.
Conflict because portal_service/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in portal_service/wizard/__init__.py
Contents conflict in portal_service/wizard/case_get_open.py
Conflict: can't delete portal_training because it is not empty.  Not deleting.
Conflict because portal_training is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete product_catalog_report because it is not empty.  Not deleting.
Conflict because product_catalog_report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_catalog_report/__init__.py
Contents conflict in product_catalog_report/__terp__.py
Conflict: can't delete product_catalog_report/report because it is not empty.  Not deleting.
Conflict because product_catalog_report/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_catalog_report/report/__init__.py
Contents conflict in product_catalog_report/report/product_catalog.py
Contents conflict in product_catalog_report/report/product_catalog.rml
Conflict: can't delete product_catalog_report/wizard because it is not empty.  Not deleting.
Conflict because product_catalog_report/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_catalog_report/wizard/__init__.py
Contents conflict in product_catalog_report/wizard/wizard_product_catalog.py
Conflict: can't delete product_electronic because it is not empty.  Not deleting.
Conflict because product_electronic is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_electronic/__init__.py
Contents conflict in product_electronic/__terp__.py
Contents conflict in product_electronic/product_electronic.py
Contents conflict in product_electronic/product_electronic_view.xml
Conflict: can't delete product_extended because it is not empty.  Not deleting.
Conflict because product_extended is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_extended/__init__.py
Contents conflict in product_extended/__terp__.py
Conflict: can't delete product_extended/i18n because it is not empty.  Not deleting.
Conflict because product_extended/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_extended/product_extended.py
Conflict: can't delete product_gtin because it is not empty.  Not deleting.
Conflict because product_gtin is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_gtin/__terp__.py
Conflict: can't delete product_index because it is not empty.  Not deleting.
Conflict because product_index is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_index/__init__.py
Contents conflict in product_index/__terp__.py
Contents conflict in product_index/product_index.py
Contents conflict in product_index/product_index_view.xml
Conflict: can't delete product_listprice_upgrade because it is not empty.  Not deleting.
Conflict because product_listprice_upgrade is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_listprice_upgrade/__init__.py
Contents conflict in product_listprice_upgrade/__terp__.py
Conflict: can't delete product_listprice_upgrade/wizard because it is not empty.  Not deleting.
Conflict because product_listprice_upgrade/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_listprice_upgrade/wizard/__init__.py
Contents conflict in product_listprice_upgrade/wizard/wizard_product_listprice.py
Conflict: can't delete product_lot_foundry because it is not empty.  Not deleting.
Conflict because product_lot_foundry is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_lot_foundry/__init__.py
Contents conflict in product_lot_foundry/__terp__.py
Contents conflict in product_lot_foundry/product_lot_foundry.py
Contents conflict in product_lot_foundry/purchase_auto.py
Conflict: can't delete product_m2mcategories because it is not empty.  Not deleting.
Conflict because product_m2mcategories is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete product_qt because it is not empty.  Not deleting.
Conflict because product_qt is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_qt/__terp__.py
Conflict: can't delete product_search_reference because it is not empty.  Not deleting.
Conflict because product_search_reference is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_search_reference/__init__.py
Contents conflict in product_search_reference/__terp__.py
Contents conflict in product_search_reference/product.py
Conflict: can't delete product_series because it is not empty.  Not deleting.
Conflict because product_series is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_series/product_series_view.xml
Conflict: can't delete product_size because it is not empty.  Not deleting.
Conflict because product_size is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_size/__init__.py
Contents conflict in product_size/__terp__.py
Contents conflict in product_size/product_size.py
Conflict: can't delete product_variant_configurator because it is not empty.  Not deleting.
Conflict because product_variant_configurator is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete product_variant_configurator/i18n because it is not empty.  Not deleting.
Conflict because product_variant_configurator/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete product_variant_multi because it is not empty.  Not deleting.
Conflict because product_variant_multi is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_variant_multi/demo_data.xml
Conflict: can't delete product_variant_multi/i18n because it is not empty.  Not deleting.
Conflict because product_variant_multi/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_variant_multi/i18n/product_variant_multi.pot
Contents conflict in product_variant_multi/product_variant.py
Contents conflict in product_variant_multi/product_view.xml
Conflict: can't delete product_variant_multi/security because it is not empty.  Not deleting.
Conflict because product_variant_multi/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in product_variant_multi/security/ir.model.access.csv
Conflict: can't delete productivity_analysis because it is not empty.  Not deleting.
Conflict because productivity_analysis is not versioned, but has versioned children.  Versioned directory.
Contents conflict in productivity_analysis/__init__.py
Contents conflict in productivity_analysis/__terp__.py
Contents conflict in productivity_analysis/productivity_analysis.py
Conflict: can't delete productivity_analysis/report because it is not empty.  Not deleting.
Conflict because productivity_analysis/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in productivity_analysis/report/__init__.py
Contents conflict in productivity_analysis/report/productivity_analysis.py
Conflict: can't delete productivity_analysis/wizard because it is not empty.  Not deleting.
Conflict because productivity_analysis/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in productivity_analysis/wizard/__init__.py
Contents conflict in productivity_analysis/wizard/wizard_pa_report.py
Conflict: can't delete profile_account_india because it is not empty.  Not deleting.
Conflict because profile_account_india is not versioned, but has versioned children.  Versioned directory.
Contents conflict in profile_account_india/__init__.py
Contents conflict in profile_account_india/__terp__.py
Conflict: can't delete profile_ampco because it is not empty.  Not deleting.
Conflict because profile_ampco is not versioned, but has versioned children.  Versioned directory.
Contents conflict in profile_ampco/__init__.py
Contents conflict in profile_ampco/__terp__.py
Conflict: can't delete profile_bi because it is not empty.  Not deleting.
Conflict because profile_bi is not versioned, but has versioned children.  Versioned directory.
Contents conflict in profile_bi/__init__.py
Contents conflict in profile_bi/__terp__.py
Conflict: can't delete profile_bookstore because it is not empty.  Not deleting.
Conflict because profile_bookstore is not versioned, but has versioned children.  Versioned directory.
Contents conflict in profile_bookstore/__init__.py
Contents conflict in profile_bookstore/__terp__.py
Conflict: can't delete profile_business_game because it is not empty.  Not deleting.
Conflict because profile_business_game is not versioned, but has versioned children.  Versioned directory.
Contents conflict in profile_business_game/__terp__.py
Contents conflict in profile_business_game/profile_game_config.xml
Contents conflict in profile_business_game/profile_game_data.xml
Conflict: can't delete profile_cci because it is not empty.  Not deleting.
Conflict because profile_cci is not versioned, but has versioned children.  Versioned directory.
Contents conflict in profile_cci/__init__.py
Contents conflict in profile_cci/__terp__.py
Conflict: can't delete profile_dm because it is not empty.  Not deleting.
Conflict because profile_dm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in profile_dm/__terp__.py
Conflict: can't delete profile_hotel because it is not empty.  Not deleting.
Conflict because profile_hotel is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete profile_training because it is not empty.  Not deleting.
Conflict because profile_training is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete proforma_followup because it is not empty.  Not deleting.
Conflict because proforma_followup is not versioned, but has versioned children.  Versioned directory.
Contents conflict in proforma_followup/proforma.py
Conflict: can't delete project_contact because it is not empty.  Not deleting.
Conflict because project_contact is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete project_crm because it is not empty.  Not deleting.
Conflict because project_crm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in project_crm/__terp__.py
Contents conflict in project_crm/project_crm.py
Conflict: can't delete project_event because it is not empty.  Not deleting.
Conflict because project_event is not versioned, but has versioned children.  Versioned directory.
Contents conflict in project_event/project_event.py
Conflict: can't delete project_idea because it is not empty.  Not deleting.
Conflict because project_idea is not versioned, but has versioned children.  Versioned directory.
Contents conflict in project_idea/__terp__.py
Conflict: can't delete project_timesheet_contract because it is not empty.  Not deleting.
Conflict because project_timesheet_contract is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete purchase_approve because it is not empty.  Not deleting.
Conflict because purchase_approve is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_approve/__init__.py
Contents conflict in purchase_approve/__terp__.py
Conflict: can't delete purchase_confirm because it is not empty.  Not deleting.
Conflict because purchase_confirm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_confirm/__init__.py
Contents conflict in purchase_confirm/__terp__.py
Conflict: can't delete purchase_confirm/wizard because it is not empty.  Not deleting.
Conflict because purchase_confirm/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_confirm/wizard/__init__.py
Contents conflict in purchase_confirm/wizard/po_confirm.py
Conflict: can't delete purchase_delivery because it is not empty.  Not deleting.
Conflict because purchase_delivery is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_delivery/__init__.py
Contents conflict in purchase_delivery/__terp__.py
Contents conflict in purchase_delivery/delivery.py
Contents conflict in purchase_delivery/purchase.py
Conflict: can't delete purchase_delivery/wizard because it is not empty.  Not deleting.
Conflict because purchase_delivery/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_delivery/wizard/__init__.py
Contents conflict in purchase_delivery/wizard/delivery_purchase_order.py
Conflict: can't delete purchase_discount because it is not empty.  Not deleting.
Conflict because purchase_discount is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_discount/__init__.py
Contents conflict in purchase_discount/__terp__.py
Contents conflict in purchase_discount/purchase_discount.py
Conflict: can't delete purchase_discount/report because it is not empty.  Not deleting.
Conflict because purchase_discount/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_discount/report/__init__.py
Contents conflict in purchase_discount/report/order.py
Conflict: can't delete purchase_journal because it is not empty.  Not deleting.
Conflict because purchase_journal is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_journal/__init__.py
Contents conflict in purchase_journal/__terp__.py
Contents conflict in purchase_journal/purchase_journal.py
Contents conflict in purchase_journal/purchase_journal_inherit.py
Contents conflict in purchase_journal/purchase_journal_report.py
Conflict: can't delete purchase_number because it is not empty.  Not deleting.
Conflict because purchase_number is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete purchase_tax_include because it is not empty.  Not deleting.
Conflict because purchase_tax_include is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_tax_include/__init__.py
Contents conflict in purchase_tax_include/purchase_tax_incl.py
Contents conflict in purchase_tax_include/purchase_tax_incl.xml
Conflict: can't delete purchase_tender because it is not empty.  Not deleting.
Conflict because purchase_tender is not versioned, but has versioned children.  Versioned directory.
Contents conflict in purchase_tender/__init__.py
Contents conflict in purchase_tender/__terp__.py
Conflict: can't delete radiotv because it is not empty.  Not deleting.
Conflict because radiotv is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete radiotv/i18n because it is not empty.  Not deleting.
Conflict because radiotv/i18n is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete radiotv/wizard because it is not empty.  Not deleting.
Conflict because radiotv/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in radiotv/wizard/wizard_copy_broadcasts.py
Contents conflict in radiotv/wizard/wizard_export_broadcasts.py
Contents conflict in radiotv/wizard/wizard_export_channels_programs.py
Contents conflict in radiotv/wizard/wizard_export_podcasts.py
Conflict: can't delete report_analytic2 because it is not empty.  Not deleting.
Conflict because report_analytic2 is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_analytic2/__terp__.py
Conflict: can't delete report_analytic_planning_delegate because it is not empty.  Not deleting.
Conflict because report_analytic_planning_delegate is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_analytic_planning_delegate/__init__.py
Contents conflict in report_analytic_planning_delegate/__terp__.py
Contents conflict in report_analytic_planning_delegate/report_analytic_planning.py
Contents conflict in report_analytic_planning_delegate/report_analytic_planning_view.xml
Conflict: can't delete report_analytic_planning_long_term because it is not empty.  Not deleting.
Conflict because report_analytic_planning_long_term is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_analytic_planning_long_term/__init__.py
Contents conflict in report_analytic_planning_long_term/__terp__.py
Contents conflict in report_analytic_planning_long_term/report_analytic_planning_long_term.py
Contents conflict in report_analytic_planning_long_term/report_analytic_planning_long_term_view.xml
Conflict: can't delete report_auction because it is not empty.  Not deleting.
Conflict because report_auction is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_auction/__init__.py
Contents conflict in report_auction/__terp__.py
Contents conflict in report_auction/report_auction.py
Conflict: can't delete report_dm because it is not empty.  Not deleting.
Conflict because report_dm is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_dm/__terp__.py
Conflict: can't delete report_hotel_reservation because it is not empty.  Not deleting.
Conflict because report_hotel_reservation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_hotel_reservation/__terp__.py
Conflict: can't delete report_hotel_restaurant because it is not empty.  Not deleting.
Conflict because report_hotel_restaurant is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete report_timesheet_user because it is not empty.  Not deleting.
Conflict because report_timesheet_user is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_timesheet_user/__init__.py
Contents conflict in report_timesheet_user/__terp__.py
Contents conflict in report_timesheet_user/report_timesheet_user.py
Conflict: can't delete report_timesheet_user/security because it is not empty.  Not deleting.
Conflict because report_timesheet_user/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in report_timesheet_user/security/ir.model.access.csv
Conflict: can't delete sale_advertising because it is not empty.  Not deleting.
Conflict because sale_advertising is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_advertising/__init__.py
Contents conflict in sale_advertising/__terp__.py
Contents conflict in sale_advertising/sale_advertising.py
Contents conflict in sale_advertising/sale_advertising_demo.xml
Contents conflict in sale_advertising/sale_advertising_view.xml
Conflict: can't delete sale_advertising/security because it is not empty.  Not deleting.
Conflict because sale_advertising/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_advertising/security/ir.model.access.csv
Conflict: can't delete sale_category because it is not empty.  Not deleting.
Conflict because sale_category is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_category/__init__.py
Contents conflict in sale_category/__terp__.py
Conflict: can't delete sale_category/report because it is not empty.  Not deleting.
Conflict because sale_category/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_category/report/__init__.py
Contents conflict in sale_category/report/sale_category_report.py
Contents conflict in sale_category/sale.py
Conflict: can't delete sale_delivery because it is not empty.  Not deleting.
Conflict because sale_delivery is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_delivery/__init__.py
Contents conflict in sale_delivery/__terp__.py
Contents conflict in sale_delivery/sale_delivery.py
Conflict: can't delete sale_delivery/security because it is not empty.  Not deleting.
Conflict because sale_delivery/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_delivery/security/ir.model.access.csv
Conflict: can't delete sale_expected_invoice_date because it is not empty.  Not deleting.
Conflict because sale_expected_invoice_date is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_expected_invoice_date/__init__.py
Contents conflict in sale_expected_invoice_date/__terp__.py
Contents conflict in sale_expected_invoice_date/sale_expected_invoice_date.py
Conflict: can't delete sale_forecast because it is not empty.  Not deleting.
Conflict because sale_forecast is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_forecast/__init__.py
Contents conflict in sale_forecast/__openerp__.py
Conflict: can't delete sale_forecast/report because it is not empty.  Not deleting.
Conflict because sale_forecast/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_forecast/report/__init__.py
Contents conflict in sale_forecast/report/sale_forecast_salesman.py
Contents conflict in sale_forecast/report/sale_forecasts_report.py
Contents conflict in sale_forecast/sale_forecast.py
Contents conflict in sale_forecast/sale_forecast_view.xml
Conflict: can't delete sale_forecast/security because it is not empty.  Not deleting.
Conflict because sale_forecast/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_forecast/security/ir.model.access.csv
Conflict: can't delete sale_forecast/wizard because it is not empty.  Not deleting.
Conflict because sale_forecast/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_forecast/wizard/__init__.py
Contents conflict in sale_forecast/wizard/sale_forecast_wizard.py
Conflict: can't delete sale_intercompany because it is not empty.  Not deleting.
Conflict because sale_intercompany is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete sale_intercompany/wizard because it is not empty.  Not deleting.
Conflict because sale_intercompany/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_intercompany/wizard/makesale.py
Conflict: can't delete sale_intercompany_auto because it is not empty.  Not deleting.
Conflict because sale_intercompany_auto is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_intercompany_auto/__init__.py
Contents conflict in sale_intercompany_auto/__terp__.py
Contents conflict in sale_intercompany_auto/sale_interco.py
Conflict: can't delete sale_margin_delivery because it is not empty.  Not deleting.
Conflict because sale_margin_delivery is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_margin_delivery/__init__.py
Contents conflict in sale_margin_delivery/__terp__.py
Contents conflict in sale_margin_delivery/sale_margin_delivery.py
Conflict: can't delete sale_numbers because it is not empty.  Not deleting.
Conflict because sale_numbers is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_numbers/__init__.py
Contents conflict in sale_numbers/__terp__.py
Conflict: can't delete sale_numbers/report because it is not empty.  Not deleting.
Conflict because sale_numbers/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_numbers/report/__init__.py
Contents conflict in sale_numbers/report/sale_order.py
Contents conflict in sale_numbers/sale_order.py
Conflict: can't delete sale_payment because it is not empty.  Not deleting.
Conflict because sale_payment is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_payment/__init__.py
Conflict: can't delete sale_payment/i18n because it is not empty.  Not deleting.
Conflict because sale_payment/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_payment/sale_payment.py
Contents conflict in sale_payment/sale_payment_view.xml
Conflict: can't delete sale_product_multistep_configurator because it is not empty.  Not deleting.
Conflict because sale_product_multistep_configurator is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_product_multistep_configurator/__init__.py
Conflict: can't delete sale_product_multistep_configurator/i18n because it is not empty.  Not deleting.
Conflict because sale_product_multistep_configurator/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_product_multistep_configurator/sale_product_multistep_configurator.py
Contents conflict in sale_product_multistep_configurator/sale_product_multistep_configurator.xml
Conflict: can't delete sale_product_multistep_configurator/security because it is not empty.  Not deleting.
Conflict because sale_product_multistep_configurator/security is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_product_multistep_configurator/security/ir.model.access.csv
Conflict: can't delete sale_rebate because it is not empty.  Not deleting.
Conflict because sale_rebate is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_rebate/__init__.py
Contents conflict in sale_rebate/__terp__.py
Contents conflict in sale_rebate/sale.py
Conflict: can't delete sale_supplier_direct_delivery because it is not empty.  Not deleting.
Conflict because sale_supplier_direct_delivery is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_supplier_direct_delivery/__init__.py
Contents conflict in sale_supplier_direct_delivery/mrp.py
Contents conflict in sale_supplier_direct_delivery/partner.py
Contents conflict in sale_supplier_direct_delivery/product.py
Contents conflict in sale_supplier_direct_delivery/purchase.py
Conflict: can't delete sale_supplier_direct_delivery/report because it is not empty.  Not deleting.
Conflict because sale_supplier_direct_delivery/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_supplier_direct_delivery/report/__init__.py
Contents conflict in sale_supplier_direct_delivery/report/supplier_report.py
Contents conflict in sale_supplier_direct_delivery/sale.py
Contents conflict in sale_supplier_direct_delivery/stock.py
Conflict: can't delete sale_tax_include because it is not empty.  Not deleting.
Conflict because sale_tax_include is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_tax_include/__init__.py
Contents conflict in sale_tax_include/__terp__.py
Conflict: can't delete sale_tax_include/i18n because it is not empty.  Not deleting.
Conflict because sale_tax_include/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_tax_include/sale_tax_incl.py
Contents conflict in sale_tax_include/sale_tax_incl.xml
Conflict: can't delete sale_wo_prices because it is not empty.  Not deleting.
Conflict because sale_wo_prices is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete sale_wo_production because it is not empty.  Not deleting.
Conflict because sale_wo_production is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sale_wo_production/__init__.py
Contents conflict in sale_wo_production/__terp__.py
Conflict: can't delete sales_purchase_seq because it is not empty.  Not deleting.
Conflict because sales_purchase_seq is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sales_purchase_seq/__init__.py
Contents conflict in sales_purchase_seq/__terp__.py
Contents conflict in sales_purchase_seq/sales_purchase_seq.py
Conflict: can't delete sales_server_action because it is not empty.  Not deleting.
Conflict because sales_server_action is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sales_server_action/__init__.py
Contents conflict in sales_server_action/__terp__.py
Conflict: can't delete sandwich because it is not empty.  Not deleting.
Conflict because sandwich is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sandwich/__init__.py
Contents conflict in sandwich/__terp__.py
Conflict: can't delete sandwich/report because it is not empty.  Not deleting.
Conflict because sandwich/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sandwich/report/__init__.py
Contents conflict in sandwich/report/sandwich_report.py
Contents conflict in sandwich/sandwich.py
Conflict: can't delete sandwich/wizard because it is not empty.  Not deleting.
Conflict because sandwich/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in sandwich/wizard/__init__.py
Contents conflict in sandwich/wizard/order_create.py
Contents conflict in sandwich/wizard/sandwich_wizard.py
Conflict: can't delete scripts because it is not empty.  Not deleting.
Conflict because scripts is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete scripts/tinyerp_demo because it is not empty.  Not deleting.
Conflict because scripts/tinyerp_demo is not versioned, but has versioned children.  Versioned directory.
Contents conflict in scripts/tinyerp_demo/create_demo_db.py
Conflict: can't delete segmentation because it is not empty.  Not deleting.
Conflict because segmentation is not versioned, but has versioned children.  Versioned directory.
Contents conflict in segmentation/__init__.py
Contents conflict in segmentation/__terp__.py
Contents conflict in segmentation/segmentation.py
Conflict: can't delete segmentation/wizard because it is not empty.  Not deleting.
Conflict because segmentation/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in segmentation/wizard/__init__.py
Contents conflict in segmentation/wizard/open_partner.py
Conflict: can't delete smsclient because it is not empty.  Not deleting.
Conflict because smsclient is not versioned, but has versioned children.  Versioned directory.
Contents conflict in smsclient/__init__.py
Contents conflict in smsclient/__terp__.py
Contents conflict in smsclient/serveraction.py
Contents conflict in smsclient/smsclient.py
Conflict: can't delete smsclient/wizard because it is not empty.  Not deleting.
Conflict because smsclient/wizard is not versioned, but has versioned children.  Versioned directory.
Contents conflict in smsclient/wizard/__init__.py
Contents conflict in smsclient/wizard/mass_sms.py
Contents conflict in smsclient/wizard/sendcode.py
Contents conflict in smsclient/wizard/verifycode.py
Conflict: can't delete stock_location_pull because it is not empty.  Not deleting.
Conflict because stock_location_pull is not versioned, but has versioned children.  Versioned directory.
Contents conflict in stock_location_pull/__init__.py
Contents conflict in stock_location_pull/__terp__.py
Conflict: can't delete stock_location_pull/i18n because it is not empty.  Not deleting.
Conflict because stock_location_pull/i18n is not versioned, but has versioned children.  Versioned directory.
Contents conflict in stock_location_pull/i18n/pt_BR.po
Contents conflict in stock_location_pull/i18n/zh_CN.po
Contents conflict in stock_location_pull/i18n/zh_TW.po
Contents conflict in stock_location_pull/mrp_pull.py
Contents conflict in stock_location_pull/mrp_pull_workflow.xml
Contents conflict in stock_location_pull/stock.py
Contents conflict in stock_location_pull/stock_view.xml
Conflict: can't delete test_44 because it is not empty.  Not deleting.
Conflict because test_44 is not versioned, but has versioned children.  Versioned directory.
Contents conflict in test_44/__init__.py
Contents conflict in test_44/__terp__.py
Contents conflict in test_44/test.py
Conflict: can't delete test_server because it is not empty.  Not deleting.
Conflict because test_server is not versioned, but has versioned children.  Versioned directory.
Contents conflict in test_server/__terp__.py
Conflict: can't delete tiny_purchase because it is not empty.  Not deleting.
Conflict because tiny_purchase is not versioned, but has versioned children.  Versioned directory.
Contents conflict in tiny_purchase/__init__.py
Contents conflict in tiny_purchase/__terp__.py
Conflict: can't delete tiny_purchase/report because it is not empty.  Not deleting.
Conflict because tiny_purchase/report is not versioned, but has versioned children.  Versioned directory.
Contents conflict in tiny_purchase/report/__init__.py
Contents conflict in tiny_purchase/report/tiny_purchase_order_report.py
Contents conflict in tiny_purchase/tiny_purchase.py
Conflict: can't delete travel because it is not empty.  Not deleting.
Conflict because travel is not versioned, but has versioned children.  Versioned directory.
Contents conflict in travel/__init__.py
Contents conflict in travel/__terp__.py
Contents conflict in travel/custom.py
Conflict: can't delete user_ctg because it is not empty.  Not deleting.
Conflict because user_ctg is not versioned, but has versioned children.  Versioned directory.
Contents conflict in user_ctg/__init__.py
Contents conflict in user_ctg/__terp__.py
Contents conflict in user_ctg/lp_server.py
Contents conflict in user_ctg/user_ctg.py
Contents conflict in user_ctg/user_ctg_data.xml
Contents conflict in user_ctg/user_ctg_view.xml
Conflict: can't delete virustotal because it is not empty.  Not deleting.
Conflict because virustotal is not versioned, but has versioned children.  Versioned directory.
Contents conflict in virustotal/__init__.py
Contents conflict in virustotal/__terp__.py
Contents conflict in virustotal/attachment.py
Conflict: can't delete webmail because it is not empty.  Not deleting.
Conflict because webmail is not versioned, but has versioned children.  Versioned directory.
Contents conflict in webmail/webmail.py
Conflict: can't delete wizard_access_rules because it is not empty.  Not deleting.
Conflict because wizard_access_rules is not versioned, but has versioned children.  Versioned directory.
Contents conflict in wizard_access_rules/__init__.py
Contents conflict in wizard_access_rules/__terp__.py
Contents conflict in wizard_access_rules/wizard_acl.py
Contents conflict in wizard_access_rules/wizard_acl_view.xml
Conflict: can't delete zarafa because it is not empty.  Not deleting.
Conflict because zarafa is not versioned, but has versioned children.  Versioned directory.
To merge this branch: bzr merge lp:~npg-team/openobject-addons/partner_address_validation__npg
Reviewer Review Type Date Requested Status
Numérigraphe wrong parent branch Needs Resubmitting
Review via email: mp+78442@code.launchpad.net

Description of the change

NovaPoint Group has developed this module to provide the ability to do address validation for US via UPS.

To post a comment you must log in.
Revision history for this message
Numérigraphe (numerigraphe) wrote :

The number of conflicts make me think you submitted your proposal to the wrong branch.
Maybe you should bundle your module on a dedicated branch?
Lionel Sausin

Revision history for this message
Numérigraphe (numerigraphe) :
review: Needs Resubmitting (wrong parent branch)

Unmerged revisions

5306. By Novapoint Group

[Add]: partner_address_validation to provide partner address validation via UPS

5305. By Xavier (Open ERP)

[ADD] modifiers setup on account.move.line override of fields_view_get

this way, the web clients correctly gets @required fields, and hides the columns which should be hidden

5304. By Stephane Wirtel (OpenERP)

[FIX] base_setup: Set the right xml_id for the hidden/link category

5303. By Stephane Wirtel (OpenERP)

[FIX] base_setup: Set the right modules of the category

5302. By Stephane Wirtel (OpenERP)

[FIX] base_setup: Fix a problem with categories to show

5301. By Olivier Dony (Odoo)

[IMP] account_invoice_layout: missing state field in list view (used for `states` modifiers)

5300. By Launchpad Translations on behalf of openerp

Launchpad automatic translations update.

5299. By Antony Lesuisse (OpenERP)

[FIX] packaging rename doc python rpm build does not tolerate spaces in files

5298. By Antony Lesuisse (OpenERP)

[FIX] packaging rename doc python rpm build does not tolerate spaces in files

5297. By Antony Lesuisse (OpenERP)

[FIX] crm tests, openid import

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2011-10-06 16:09:39 +0000
@@ -0,0 +1,1 @@
1.*
02
=== renamed file '.bzrignore' => '.bzrignore.moved'
=== added directory 'account'
=== added file 'account/__init__.py'
--- account/__init__.py 1970-01-01 00:00:00 +0000
+++ account/__init__.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,39 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import account
23import installer
24import project
25import partner
26import account_invoice
27import account_bank_statement
28import account_bank
29import account_cash_statement
30import account_move_line
31import account_analytic_line
32import wizard
33import report
34import product
35import ir_sequence
36import company
37import res_currency
38
39# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
040
=== added file 'account/__openerp__.py'
--- account/__openerp__.py 1970-01-01 00:00:00 +0000
+++ account/__openerp__.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,156 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21{
22 "name" : "Accounting and Financial Management",
23 "version" : "1.1",
24 "author" : "OpenERP SA",
25 "category": 'Accounting & Finance',
26 'complexity': "normal",
27 "description": """
28Accounting and Financial Management.
29====================================
30
31Financial and accounting module that covers:
32--------------------------------------------
33General accountings
34Cost / Analytic accounting
35Third party accounting
36Taxes management
37Budgets
38Customer and Supplier Invoices
39Bank statements
40Reconciliation process by partner
41
42Creates a dashboard for accountants that includes:
43--------------------------------------------------
44* List of Customer Invoice to Approve
45* Company Analysis
46* Graph of Aged Receivables
47* Graph of Treasury
48
49The processes like maintaining of general ledger is done through the defined financial Journals (entry move line or
50grouping is maintained through journal) for a particular financial year and for preparation of vouchers there is a
51module named account_voucher.
52 """,
53 'website': 'http://www.openerp.com',
54 'images' : ['images/accounts.jpeg','images/bank_statement.jpeg','images/cash_register.jpeg','images/chart_of_accounts.jpeg','images/customer_invoice.jpeg','images/journal_entries.jpeg'],
55 'init_xml': [],
56 "depends" : ["base_setup", "product", "analytic", "process","board"],
57 'update_xml': [
58 'security/account_security.xml',
59 'security/ir.model.access.csv',
60 'account_menuitem.xml',
61 'report/account_invoice_report_view.xml',
62 'report/account_entries_report_view.xml',
63 'report/account_treasury_report_view.xml',
64 'report/account_report_view.xml',
65 'report/account_analytic_entries_report_view.xml',
66 'wizard/account_move_bank_reconcile_view.xml',
67 'wizard/account_use_model_view.xml',
68 'account_installer.xml',
69 'wizard/account_period_close_view.xml',
70 'account_view.xml',
71 'account_report.xml',
72 'wizard/account_report_common_view.xml',
73 'wizard/account_invoice_refund_view.xml',
74 'wizard/account_fiscalyear_close_state.xml',
75 'wizard/account_chart_view.xml',
76 'wizard/account_tax_chart_view.xml',
77 'wizard/account_move_journal_view.xml',
78 'wizard/account_move_line_reconcile_select_view.xml',
79 'wizard/account_open_closed_fiscalyear_view.xml',
80 'wizard/account_move_line_unreconcile_select_view.xml',
81 'wizard/account_vat_view.xml',
82 'wizard/account_report_print_journal_view.xml',
83 'wizard/account_report_general_journal_view.xml',
84 'wizard/account_report_central_journal_view.xml',
85 'wizard/account_subscription_generate_view.xml',
86 'wizard/account_fiscalyear_close_view.xml',
87 'wizard/account_state_open_view.xml',
88 'wizard/account_journal_select_view.xml',
89 'wizard/account_change_currency_view.xml',
90 'wizard/account_validate_move_view.xml',
91 'wizard/account_unreconcile_view.xml',
92 'wizard/account_report_general_ledger_view.xml',
93 'wizard/account_invoice_state_view.xml',
94 'wizard/account_report_partner_balance_view.xml',
95 'wizard/account_report_account_balance_view.xml',
96 'wizard/account_report_aged_partner_balance_view.xml',
97 'wizard/account_report_partner_ledger_view.xml',
98 'wizard/account_reconcile_view.xml',
99 'wizard/account_reconcile_partner_process_view.xml',
100 'wizard/account_automatic_reconcile_view.xml',
101 'wizard/account_financial_report_view.xml',
102 'project/wizard/project_account_analytic_line_view.xml',
103 'account_end_fy.xml',
104 'account_invoice_view.xml',
105 'partner_view.xml',
106 'data/account_data.xml',
107 'account_invoice_workflow.xml',
108 'project/project_view.xml',
109 'project/project_report.xml',
110 'project/wizard/account_analytic_balance_report_view.xml',
111 'project/wizard/account_analytic_cost_ledger_view.xml',
112 'project/wizard/account_analytic_inverted_balance_report.xml',
113 'project/wizard/account_analytic_journal_report_view.xml',
114 'project/wizard/account_analytic_cost_ledger_for_journal_report_view.xml',
115 'project/wizard/account_analytic_chart_view.xml',
116 'product_view.xml',
117 'account_assert_test.xml',
118 'process/statement_process.xml',
119 'process/customer_invoice_process.xml',
120 'process/supplier_invoice_process.xml',
121 'ir_sequence_view.xml',
122 'company_view.xml',
123 'board_account_view.xml',
124 "wizard/account_report_profit_loss_view.xml",
125 "wizard/account_report_balance_sheet_view.xml",
126 "account_bank_view.xml"
127 ],
128 'demo_xml': [
129 'demo/account_demo.xml',
130 'project/project_demo.xml',
131 'project/analytic_account_demo.xml',
132 'demo/account_minimal.xml',
133 'demo/account_invoice_demo.xml',
134# 'account_unit_test.xml',
135 ],
136 'test': [
137 'test/account_customer_invoice.yml',
138 'test/account_supplier_invoice.yml',
139 'test/account_change_currency.yml',
140 'test/chart_of_account.yml',
141 'test/account_period_close.yml',
142 'test/account_fiscalyear_close_state.yml',
143 'test/account_use_model.yml',
144 'test/account_validate_account_move.yml',
145 'test/account_fiscalyear_close.yml',
146 'test/account_bank_statement.yml',
147 'test/account_cash_statement.yml',
148 'test/account_report.yml',
149
150
151 ],
152 'installable': True,
153 'active': False,
154 'certificate': '0080331923549',
155}
156# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0157
=== added file 'account/account.py'
--- account/account.py 1970-01-01 00:00:00 +0000
+++ account/account.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,3221 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import time
23from datetime import datetime
24from dateutil.relativedelta import relativedelta
25from operator import itemgetter
26
27import netsvc
28import pooler
29from osv import fields, osv
30import decimal_precision as dp
31from tools.translate import _
32
33def check_cycle(self, cr, uid, ids, context=None):
34 """ climbs the ``self._table.parent_id`` chains for 100 levels or
35 until it can't find any more parent(s)
36
37 Returns true if it runs out of parents (no cycle), false if
38 it can recurse 100 times without ending all chains
39 """
40 level = 100
41 while len(ids):
42 cr.execute('SELECT DISTINCT parent_id '\
43 'FROM '+self._table+' '\
44 'WHERE id IN %s '\
45 'AND parent_id IS NOT NULL',(tuple(ids),))
46 ids = map(itemgetter(0), cr.fetchall())
47 if not level:
48 return False
49 level -= 1
50 return True
51
52class account_payment_term(osv.osv):
53 _name = "account.payment.term"
54 _description = "Payment Term"
55 _columns = {
56 'name': fields.char('Payment Term', size=64, translate=True, required=True),
57 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the payment term without removing it."),
58 'note': fields.text('Description', translate=True),
59 'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'),
60 }
61 _defaults = {
62 'active': 1,
63 }
64 _order = "name"
65
66 def compute(self, cr, uid, id, value, date_ref=False, context=None):
67 if not date_ref:
68 date_ref = datetime.now().strftime('%Y-%m-%d')
69 pt = self.browse(cr, uid, id, context=context)
70 amount = value
71 result = []
72 obj_precision = self.pool.get('decimal.precision')
73 for line in pt.line_ids:
74 prec = obj_precision.precision_get(cr, uid, 'Account')
75 if line.value == 'fixed':
76 amt = round(line.value_amount, prec)
77 elif line.value == 'procent':
78 amt = round(value * line.value_amount, prec)
79 elif line.value == 'balance':
80 amt = round(amount, prec)
81 if amt:
82 next_date = (datetime.strptime(date_ref, '%Y-%m-%d') + relativedelta(days=line.days))
83 if line.days2 < 0:
84 next_first_date = next_date + relativedelta(day=1,months=1) #Getting 1st of next month
85 next_date = next_first_date + relativedelta(days=line.days2)
86 if line.days2 > 0:
87 next_date += relativedelta(day=line.days2, months=1)
88 result.append( (next_date.strftime('%Y-%m-%d'), amt) )
89 amount -= amt
90 return result
91
92account_payment_term()
93
94class account_payment_term_line(osv.osv):
95 _name = "account.payment.term.line"
96 _description = "Payment Term Line"
97 _columns = {
98 'name': fields.char('Line Name', size=32, required=True),
99 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the payment term lines from the lowest sequences to the higher ones"),
100 'value': fields.selection([('procent', 'Percent'),
101 ('balance', 'Balance'),
102 ('fixed', 'Fixed Amount')], 'Valuation',
103 required=True, help="""Select here the kind of valuation related to this payment term line. Note that you should have your last line with the type 'Balance' to ensure that the whole amount will be threated."""),
104
105 'value_amount': fields.float('Amount To Pay', digits_compute=dp.get_precision('Payment Term'), help="For percent enter a ratio between 0-1."),
106 'days': fields.integer('Number of Days', required=True, help="Number of days to add before computation of the day of month." \
107 "If Date=15/01, Number of Days=22, Day of Month=-1, then the due date is 28/02."),
108 'days2': fields.integer('Day of the Month', required=True, help="Day of the month, set -1 for the last day of the current month. If it's positive, it gives the day of the next month. Set 0 for net days (otherwise it's based on the beginning of the month)."),
109 'payment_id': fields.many2one('account.payment.term', 'Payment Term', required=True, select=True),
110 }
111 _defaults = {
112 'value': 'balance',
113 'sequence': 5,
114 'days2': 0,
115 }
116 _order = "sequence"
117
118 def _check_percent(self, cr, uid, ids, context=None):
119 obj = self.browse(cr, uid, ids[0], context=context)
120 if obj.value == 'procent' and ( obj.value_amount < 0.0 or obj.value_amount > 1.0):
121 return False
122 return True
123
124 _constraints = [
125 (_check_percent, 'Percentages for Payment Term Line must be between 0 and 1, Example: 0.02 for 2% ', ['value_amount']),
126 ]
127
128account_payment_term_line()
129
130class account_account_type(osv.osv):
131 _name = "account.account.type"
132 _description = "Account Type"
133 _columns = {
134 'name': fields.char('Account Type', size=64, required=True),
135 'code': fields.char('Code', size=32, required=True),
136 'close_method': fields.selection([('none', 'None'), ('balance', 'Balance'), ('detail', 'Detail'), ('unreconciled', 'Unreconciled')], 'Deferral Method', required=True, help="""Set here the method that will be used to generate the end of year journal entries for all the accounts of this type.
137
138 'None' means that nothing will be done.
139 'Balance' will generally be used for cash accounts.
140 'Detail' will copy each existing journal item of the previous year, even the reconciled ones.
141 'Unreconciled' will copy only the journal items that were unreconciled on the first day of the new fiscal year."""),
142 'sign': fields.selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.'),
143 'report_type':fields.selection([
144 ('none','/'),
145 ('income','Profit & Loss (Income Accounts)'),
146 ('expense','Profit & Loss (Expense Accounts)'),
147 ('asset','Balance Sheet (Assets Accounts)'),
148 ('liability','Balance Sheet (Liability Accounts)')
149 ],'P&L / BS Category', select=True, readonly=False, help="This field is used to generate legal reports: profit and loss, balance sheet.", required=True),
150 'note': fields.text('Description'),
151 }
152 _defaults = {
153 'close_method': 'none',
154 'sign': 1,
155 'report_type': 'none',
156 }
157 _order = "code"
158
159account_account_type()
160
161def _code_get(self, cr, uid, context=None):
162 acc_type_obj = self.pool.get('account.account.type')
163 ids = acc_type_obj.search(cr, uid, [])
164 res = acc_type_obj.read(cr, uid, ids, ['code', 'name'], context=context)
165 return [(r['code'], r['name']) for r in res]
166
167#----------------------------------------------------------
168# Accounts
169#----------------------------------------------------------
170
171class account_tax(osv.osv):
172 _name = 'account.tax'
173account_tax()
174
175class account_account(osv.osv):
176 _order = "parent_left"
177 _parent_order = "code"
178 _name = "account.account"
179 _description = "Account"
180 _parent_store = True
181 logger = netsvc.Logger()
182
183 def search(self, cr, uid, args, offset=0, limit=None, order=None,
184 context=None, count=False):
185 if context is None:
186 context = {}
187 pos = 0
188
189 while pos < len(args):
190
191 if args[pos][0] == 'code' and args[pos][1] in ('like', 'ilike') and args[pos][2]:
192 args[pos] = ('code', '=like', str(args[pos][2].replace('%', ''))+'%')
193 if args[pos][0] == 'journal_id':
194 if not args[pos][2]:
195 del args[pos]
196 continue
197 jour = self.pool.get('account.journal').browse(cr, uid, args[pos][2], context=context)
198 if (not (jour.account_control_ids or jour.type_control_ids)) or not args[pos][2]:
199 args[pos] = ('type','not in',('consolidation','view'))
200 continue
201 ids3 = map(lambda x: x.id, jour.type_control_ids)
202 ids1 = super(account_account, self).search(cr, uid, [('user_type', 'in', ids3)])
203 ids1 += map(lambda x: x.id, jour.account_control_ids)
204 args[pos] = ('id', 'in', ids1)
205 pos += 1
206
207 if context and context.has_key('consolidate_children'): #add consolidated children of accounts
208 ids = super(account_account, self).search(cr, uid, args, offset, limit,
209 order, context=context, count=count)
210 for consolidate_child in self.browse(cr, uid, context['account_id'], context=context).child_consol_ids:
211 ids.append(consolidate_child.id)
212 return ids
213
214 return super(account_account, self).search(cr, uid, args, offset, limit,
215 order, context=context, count=count)
216
217 def _get_children_and_consol(self, cr, uid, ids, context=None):
218 #this function search for all the children and all consolidated children (recursively) of the given account ids
219 ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context)
220 ids3 = []
221 for rec in self.browse(cr, uid, ids2, context=context):
222 for child in rec.child_consol_ids:
223 ids3.append(child.id)
224 if ids3:
225 ids3 = self._get_children_and_consol(cr, uid, ids3, context)
226 return ids2 + ids3
227
228 def __compute(self, cr, uid, ids, field_names, arg=None, context=None,
229 query='', query_params=()):
230 """ compute the balance, debit and/or credit for the provided
231 account ids
232 Arguments:
233 `ids`: account ids
234 `field_names`: the fields to compute (a list of any of
235 'balance', 'debit' and 'credit')
236 `arg`: unused fields.function stuff
237 `query`: additional query filter (as a string)
238 `query_params`: parameters for the provided query string
239 (__compute will handle their escaping) as a
240 tuple
241 """
242 mapping = {
243 'balance': "COALESCE(SUM(l.debit),0) " \
244 "- COALESCE(SUM(l.credit), 0) as balance",
245 'debit': "COALESCE(SUM(l.debit), 0) as debit",
246 'credit': "COALESCE(SUM(l.credit), 0) as credit"
247 }
248 #get all the necessary accounts
249 children_and_consolidated = self._get_children_and_consol(cr, uid, ids, context=context)
250 #compute for each account the balance/debit/credit from the move lines
251 accounts = {}
252 res = {}
253 null_result = dict((fn, 0.0) for fn in field_names)
254 if children_and_consolidated:
255 aml_query = self.pool.get('account.move.line')._query_get(cr, uid, context=context)
256
257 wheres = [""]
258 if query.strip():
259 wheres.append(query.strip())
260 if aml_query.strip():
261 wheres.append(aml_query.strip())
262 filters = " AND ".join(wheres)
263 self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG,
264 'Filters: %s'%filters)
265 # IN might not work ideally in case there are too many
266 # children_and_consolidated, in that case join on a
267 # values() e.g.:
268 # SELECT l.account_id as id FROM account_move_line l
269 # INNER JOIN (VALUES (id1), (id2), (id3), ...) AS tmp (id)
270 # ON l.account_id = tmp.id
271 # or make _get_children_and_consol return a query and join on that
272 request = ("SELECT l.account_id as id, " +\
273 ', '.join(map(mapping.__getitem__, field_names)) +
274 " FROM account_move_line l" \
275 " WHERE l.account_id IN %s " \
276 + filters +
277 " GROUP BY l.account_id")
278 params = (tuple(children_and_consolidated),) + query_params
279 cr.execute(request, params)
280 self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG,
281 'Status: %s'%cr.statusmessage)
282
283 for res in cr.dictfetchall():
284 accounts[res['id']] = res
285
286 # consolidate accounts with direct children
287 children_and_consolidated.reverse()
288 brs = list(self.browse(cr, uid, children_and_consolidated, context=context))
289 sums = {}
290 currency_obj = self.pool.get('res.currency')
291 while brs:
292 current = brs[0]
293# can_compute = True
294# for child in current.child_id:
295# if child.id not in sums:
296# can_compute = False
297# try:
298# brs.insert(0, brs.pop(brs.index(child)))
299# except ValueError:
300# brs.insert(0, child)
301# if can_compute:
302 brs.pop(0)
303 for fn in field_names:
304 sums.setdefault(current.id, {})[fn] = accounts.get(current.id, {}).get(fn, 0.0)
305 for child in current.child_id:
306 if child.company_id.currency_id.id == current.company_id.currency_id.id:
307 sums[current.id][fn] += sums[child.id][fn]
308 else:
309 sums[current.id][fn] += currency_obj.compute(cr, uid, child.company_id.currency_id.id, current.company_id.currency_id.id, sums[child.id][fn], context=context)
310 for id in ids:
311 res[id] = sums.get(id, null_result)
312 else:
313 for id in ids:
314 res[id] = null_result
315 return res
316
317 def _get_company_currency(self, cr, uid, ids, field_name, arg, context=None):
318 result = {}
319 for rec in self.browse(cr, uid, ids, context=context):
320 result[rec.id] = (rec.company_id.currency_id.id,rec.company_id.currency_id.symbol)
321 return result
322
323 def _get_child_ids(self, cr, uid, ids, field_name, arg, context=None):
324 result = {}
325 for record in self.browse(cr, uid, ids, context=context):
326 if record.child_parent_ids:
327 result[record.id] = [x.id for x in record.child_parent_ids]
328 else:
329 result[record.id] = []
330
331 if record.child_consol_ids:
332 for acc in record.child_consol_ids:
333 if acc.id not in result[record.id]:
334 result[record.id].append(acc.id)
335
336 return result
337
338 def _get_level(self, cr, uid, ids, field_name, arg, context=None):
339 res = {}
340 accounts = self.browse(cr, uid, ids, context=context)
341 for account in accounts:
342 level = 0
343 if account.parent_id:
344 obj = self.browse(cr, uid, account.parent_id.id)
345 level = obj.level + 1
346 res[account.id] = level
347 return res
348
349 def _set_credit_debit(self, cr, uid, account_id, name, value, arg, context=None):
350 if context.get('config_invisible', True):
351 return True
352
353 account = self.browse(cr, uid, account_id, context=context)
354 diff = value - getattr(account,name)
355 if not diff:
356 return True
357
358 journal_obj = self.pool.get('account.journal')
359 jids = journal_obj.search(cr, uid, [('type','=','situation'),('centralisation','=',1),('company_id','=',account.company_id.id)], context=context)
360 if not jids:
361 raise osv.except_osv(_('Error!'),_("You need an Opening journal with centralisation checked to set the initial balance!"))
362
363 period_obj = self.pool.get('account.period')
364 pids = period_obj.search(cr, uid, [('special','=',True),('company_id','=',account.company_id.id)], context=context)
365 if not pids:
366 raise osv.except_osv(_('Error!'),_("No opening/closing period defined, please create one to set the initial balance!"))
367
368 move_obj = self.pool.get('account.move.line')
369 move_id = move_obj.search(cr, uid, [
370 ('journal_id','=',jids[0]),
371 ('period_id','=',pids[0]),
372 ('account_id','=', account_id),
373 (name,'>', 0.0),
374 ('name','=', _('Opening Balance'))
375 ], context=context)
376 if move_id:
377 move = move_obj.browse(cr, uid, move_id[0], context=context)
378 move_obj.write(cr, uid, move_id[0], {
379 name: diff+getattr(move,name)
380 }, context=context)
381 else:
382 if diff<0.0:
383 raise osv.except_osv(_('Error!'),_("Unable to adapt the initial balance (negative value)!"))
384 nameinv = (name=='credit' and 'debit') or 'credit'
385 move_id = move_obj.create(cr, uid, {
386 'name': _('Opening Balance'),
387 'account_id': account_id,
388 'journal_id': jids[0],
389 'period_id': pids[0],
390 name: diff,
391 nameinv: 0.0
392 }, context=context)
393 return True
394
395 _columns = {
396 'name': fields.char('Name', size=128, required=True, select=True),
397 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
398 'code': fields.char('Code', size=64, required=True, select=1),
399 'type': fields.selection([
400 ('view', 'View'),
401 ('other', 'Regular'),
402 ('receivable', 'Receivable'),
403 ('payable', 'Payable'),
404 ('liquidity','Liquidity'),
405 ('consolidation', 'Consolidation'),
406 ('closed', 'Closed'),
407 ], 'Internal Type', required=True, help="The 'Internal Type' is used for features available on "\
408 "different types of accounts: view can not have journal items, consolidation are accounts that "\
409 "can have children accounts for multi-company consolidations, payable/receivable are for "\
410 "partners accounts (for debit/credit computations), closed for depreciated accounts."),
411 'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
412 help="Account Type is used for information purpose, to generate "
413 "country-specific legal reports, and set the rules to close a fiscal year and generate opening entries."),
414 'parent_id': fields.many2one('account.account', 'Parent', ondelete='cascade', domain=[('type','=','view')]),
415 'child_parent_ids': fields.one2many('account.account','parent_id','Children'),
416 'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
417 'child_id': fields.function(_get_child_ids, type='many2many', relation="account.account", string="Child Accounts"),
418 'balance': fields.function(__compute, digits_compute=dp.get_precision('Account'), string='Balance', multi='balance'),
419 'credit': fields.function(__compute, fnct_inv=_set_credit_debit, digits_compute=dp.get_precision('Account'), string='Credit', multi='balance'),
420 'debit': fields.function(__compute, fnct_inv=_set_credit_debit, digits_compute=dp.get_precision('Account'), string='Debit', multi='balance'),
421 'reconcile': fields.boolean('Allow Reconciliation', help="Check this box if this account allows reconciliation of journal items."),
422 'shortcut': fields.char('Shortcut', size=12),
423 'tax_ids': fields.many2many('account.tax', 'account_account_tax_default_rel',
424 'account_id', 'tax_id', 'Default Taxes'),
425 'note': fields.text('Note'),
426 'company_currency_id': fields.function(_get_company_currency, type='many2one', relation='res.currency', string='Company Currency'),
427 'company_id': fields.many2one('res.company', 'Company', required=True),
428 'active': fields.boolean('Active', select=2, help="If the active field is set to False, it will allow you to hide the account without removing it."),
429
430 'parent_left': fields.integer('Parent Left', select=1),
431 'parent_right': fields.integer('Parent Right', select=1),
432 'currency_mode': fields.selection([('current', 'At Date'), ('average', 'Average Rate')], 'Outgoing Currencies Rate',
433 help=
434 'This will select how the current currency rate for outgoing transactions is computed. '\
435 'In most countries the legal method is "average" but only a few software systems are able to '\
436 'manage this. So if you import from another software system you may have to use the rate at date. ' \
437 'Incoming transactions always use the rate at date.', \
438 required=True),
439 'level': fields.function(_get_level, string='Level', store=True, type='integer'),
440 }
441
442 _defaults = {
443 'type': 'view',
444 'reconcile': False,
445 'active': True,
446 'currency_mode': 'current',
447 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
448 }
449
450 def _check_recursion(self, cr, uid, ids, context=None):
451 obj_self = self.browse(cr, uid, ids[0], context=context)
452 p_id = obj_self.parent_id and obj_self.parent_id.id
453 if (obj_self in obj_self.child_consol_ids) or (p_id and (p_id is obj_self.id)):
454 return False
455 while(ids):
456 cr.execute('SELECT DISTINCT child_id '\
457 'FROM account_account_consol_rel '\
458 'WHERE parent_id IN %s', (tuple(ids),))
459 child_ids = map(itemgetter(0), cr.fetchall())
460 c_ids = child_ids
461 if (p_id and (p_id in c_ids)) or (obj_self.id in c_ids):
462 return False
463 while len(c_ids):
464 s_ids = self.search(cr, uid, [('parent_id', 'in', c_ids)])
465 if p_id and (p_id in s_ids):
466 return False
467 c_ids = s_ids
468 ids = child_ids
469 return True
470
471 def _check_type(self, cr, uid, ids, context=None):
472 if context is None:
473 context = {}
474 accounts = self.browse(cr, uid, ids, context=context)
475 for account in accounts:
476 if account.child_id and account.type not in ('view', 'consolidation'):
477 return False
478 return True
479
480 def _check_account_type(self, cr, uid, ids, context=None):
481 for account in self.browse(cr, uid, ids, context=context):
482 if account.type in ('receivable', 'payable') and account.user_type.close_method != 'unreconciled':
483 return False
484 return True
485
486 _constraints = [
487 (_check_recursion, 'Error ! You can not create recursive accounts.', ['parent_id']),
488 (_check_type, 'Configuration Error! \nYou can not define children to an account with internal type different of "View"! ', ['type']),
489 (_check_account_type, 'Configuration Error! \nYou can not select an account type with a deferral method different of "Unreconciled" for accounts with internal type "Payable/Receivable"! ', ['user_type','type']),
490 ]
491 _sql_constraints = [
492 ('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !')
493 ]
494 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
495 if not args:
496 args = []
497 args = args[:]
498 ids = []
499 try:
500 if name and str(name).startswith('partner:'):
501 part_id = int(name.split(':')[1])
502 part = self.pool.get('res.partner').browse(cr, user, part_id, context=context)
503 args += [('id', 'in', (part.property_account_payable.id, part.property_account_receivable.id))]
504 name = False
505 if name and str(name).startswith('type:'):
506 type = name.split(':')[1]
507 args += [('type', '=', type)]
508 name = False
509 except:
510 pass
511 if name:
512 ids = self.search(cr, user, [('code', '=like', name+"%")]+args, limit=limit)
513 if not ids:
514 ids = self.search(cr, user, [('shortcut', '=', name)]+ args, limit=limit)
515 if not ids:
516 ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit)
517 if not ids and len(name.split()) >= 2:
518 #Separating code and name of account for searching
519 operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A.
520 ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2)]+ args, limit=limit)
521 else:
522 ids = self.search(cr, user, args, context=context, limit=limit)
523 return self.name_get(cr, user, ids, context=context)
524
525 def name_get(self, cr, uid, ids, context=None):
526 if not ids:
527 return []
528 reads = self.read(cr, uid, ids, ['name', 'code'], context=context)
529 res = []
530 for record in reads:
531 name = record['name']
532 if record['code']:
533 name = record['code'] + ' ' + name
534 res.append((record['id'], name))
535 return res
536
537 def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False):
538 account = self.browse(cr, uid, id, context=context)
539 new_child_ids = []
540 if not default:
541 default = {}
542 default = default.copy()
543 default['code'] = (account['code'] or '') + '(copy)'
544 if not local:
545 done_list = []
546 if account.id in done_list:
547 return False
548 done_list.append(account.id)
549 if account:
550 for child in account.child_id:
551 child_ids = self.copy(cr, uid, child.id, default, context=context, done_list=done_list, local=True)
552 if child_ids:
553 new_child_ids.append(child_ids)
554 default['child_parent_ids'] = [(6, 0, new_child_ids)]
555 else:
556 default['child_parent_ids'] = False
557 return super(account_account, self).copy(cr, uid, id, default, context=context)
558
559 def _check_moves(self, cr, uid, ids, method, context=None):
560 line_obj = self.pool.get('account.move.line')
561 account_ids = self.search(cr, uid, [('id', 'child_of', ids)])
562
563 if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
564 if method == 'write':
565 raise osv.except_osv(_('Error !'), _('You can not desactivate an account that contains some journal items.'))
566 elif method == 'unlink':
567 raise osv.except_osv(_('Error !'), _('You can not remove an account containing journal items!. '))
568 #Checking whether the account is set as a property to any Partner or not
569 value = 'account.account,' + str(ids[0])
570 partner_prop_acc = self.pool.get('ir.property').search(cr, uid, [('value_reference','=',value)], context=context)
571 if partner_prop_acc:
572 raise osv.except_osv(_('Warning !'), _('You can not remove/desactivate an account which is set on a customer or supplier.'))
573 return True
574
575 def _check_allow_type_change(self, cr, uid, ids, new_type, context=None):
576 group1 = ['payable', 'receivable', 'other']
577 group2 = ['consolidation','view']
578 line_obj = self.pool.get('account.move.line')
579 for account in self.browse(cr, uid, ids, context=context):
580 old_type = account.type
581 account_ids = self.search(cr, uid, [('id', 'child_of', [account.id])])
582 if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
583 #Check for 'Closed' type
584 if old_type == 'closed' and new_type !='closed':
585 raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type which contains journal items!"))
586 #Check for change From group1 to group2 and vice versa
587 if (old_type in group1 and new_type in group2) or (old_type in group2 and new_type in group1):
588 raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from '%s' to '%s' type as it contains journal items!") % (old_type,new_type,))
589 return True
590
591 def write(self, cr, uid, ids, vals, context=None):
592
593 if context is None:
594 context = {}
595 if not ids:
596 return True
597 if isinstance(ids, (int, long)):
598 ids = [ids]
599
600 # Dont allow changing the company_id when account_move_line already exist
601 if 'company_id' in vals:
602 move_lines = self.pool.get('account.move.line').search(cr, uid, [('account_id', 'in', ids)])
603 if move_lines:
604 # Allow the write if the value is the same
605 for i in [i['company_id'][0] for i in self.read(cr,uid,ids,['company_id'])]:
606 if vals['company_id']!=i:
607 raise osv.except_osv(_('Warning !'), _('You cannot modify Company of account as its related record exist in Entry Lines'))
608 if 'active' in vals and not vals['active']:
609 self._check_moves(cr, uid, ids, "write", context=context)
610 if 'type' in vals.keys():
611 self._check_allow_type_change(cr, uid, ids, vals['type'], context=context)
612 return super(account_account, self).write(cr, uid, ids, vals, context=context)
613
614 def unlink(self, cr, uid, ids, context=None):
615 self._check_moves(cr, uid, ids, "unlink", context=context)
616 return super(account_account, self).unlink(cr, uid, ids, context=context)
617
618account_account()
619
620class account_journal_view(osv.osv):
621 _name = "account.journal.view"
622 _description = "Journal View"
623 _columns = {
624 'name': fields.char('Journal View', size=64, required=True),
625 'columns_id': fields.one2many('account.journal.column', 'view_id', 'Columns')
626 }
627 _order = "name"
628
629account_journal_view()
630
631
632class account_journal_column(osv.osv):
633
634 def _col_get(self, cr, user, context=None):
635 result = []
636 cols = self.pool.get('account.move.line')._columns
637 for col in cols:
638 if col in ('period_id', 'journal_id'):
639 continue
640 result.append( (col, cols[col].string) )
641 result.sort()
642 return result
643
644 _name = "account.journal.column"
645 _description = "Journal Column"
646 _columns = {
647 'name': fields.char('Column Name', size=64, required=True),
648 'field': fields.selection(_col_get, 'Field Name', required=True, size=32),
649 'view_id': fields.many2one('account.journal.view', 'Journal View', select=True),
650 'sequence': fields.integer('Sequence', help="Gives the sequence order to journal column.", readonly=True),
651 'required': fields.boolean('Required'),
652 'readonly': fields.boolean('Readonly'),
653 }
654 _order = "view_id, sequence"
655
656account_journal_column()
657
658class account_journal(osv.osv):
659 _name = "account.journal"
660 _description = "Journal"
661 _columns = {
662 'name': fields.char('Journal Name', size=64, required=True),
663 'code': fields.char('Code', size=5, required=True, help="The code will be displayed on reports."),
664 'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Cheques'), ('general', 'General'), ('situation', 'Opening/Closing Situation')], 'Type', size=32, required=True,
665 help="Select 'Sale' for customer invoices journals."\
666 " Select 'Purchase' for supplier invoices journals."\
667 " Select 'Cash' or 'Bank' for journals that are used in customer or supplier payments."\
668 " Select 'General' for miscellaneous operations journals."\
669 " Select 'Opening/Closing Situation' for entries generated for new fiscal years."),
670 'type_control_ids': fields.many2many('account.account.type', 'account_journal_type_rel', 'journal_id','type_id', 'Type Controls', domain=[('code','<>','view'), ('code', '<>', 'closed')]),
671 'account_control_ids': fields.many2many('account.account', 'account_account_type_rel', 'journal_id','account_id', 'Account', domain=[('type','<>','view'), ('type', '<>', 'closed')]),
672 'view_id': fields.many2one('account.journal.view', 'Display Mode', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tells OpenERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."),
673 'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account', domain="[('type','!=','view')]", help="It acts as a default account for credit amount"),
674 'default_debit_account_id': fields.many2one('account.account', 'Default Debit Account', domain="[('type','!=','view')]", help="It acts as a default account for debit amount"),
675 'centralisation': fields.boolean('Centralised counterpart', help="Check this box to determine that each entry of this journal won't create a new counterpart but will share the same counterpart. This is used in fiscal year closing."),
676 'update_posted': fields.boolean('Allow Cancelling Entries', help="Check this box if you want to allow the cancellation the entries related to this journal or of the invoice related to this journal"),
677 'group_invoice_lines': fields.boolean('Group Invoice Lines', help="If this box is checked, the system will try to group the accounting lines when generating them from invoices."),
678 'sequence_id': fields.many2one('ir.sequence', 'Entry Sequence', help="This field contains the informatin related to the numbering of the journal entries of this journal.", required=True),
679 'user_id': fields.many2one('res.users', 'User', help="The user responsible for this journal"),
680 'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'),
681 'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'),
682 'entry_posted': fields.boolean('Skip \'Draft\' State for Manual Entries', help='Check this box if you don\'t want new journal entries to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation. \nNote that journal entries that are automatically created by the system are always skipping that state.'),
683 'company_id': fields.many2one('res.company', 'Company', required=True, select=1, help="Company related to this journal"),
684 'allow_date':fields.boolean('Check Date in Period', help= 'If set to True then do not accept the entry if the entry date is not into the period dates'),
685 }
686
687 _defaults = {
688 'user_id': lambda self, cr, uid, context: uid,
689 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
690 }
691 _sql_constraints = [
692 ('code_company_uniq', 'unique (code, company_id)', 'The code of the journal must be unique per company !'),
693 ('name_company_uniq', 'unique (name, company_id)', 'The name of the journal must be unique per company !'),
694 ]
695
696 _order = 'code'
697
698 def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False):
699 journal = self.browse(cr, uid, id, context=context)
700 if not default:
701 default = {}
702 default = default.copy()
703 default['code'] = (journal['code'] or '') + '(copy)'
704 default['name'] = (journal['name'] or '') + '(copy)'
705 default['sequence_id'] = False
706 return super(account_journal, self).copy(cr, uid, id, default, context=context)
707
708 def write(self, cr, uid, ids, vals, context=None):
709 if context is None:
710 context = {}
711 if isinstance(ids, (int, long)):
712 ids = [ids]
713 for journal in self.browse(cr, uid, ids, context=context):
714 if 'company_id' in vals and journal.company_id.id != vals['company_id']:
715 move_lines = self.pool.get('account.move.line').search(cr, uid, [('journal_id', 'in', ids)])
716 if move_lines:
717 raise osv.except_osv(_('Warning !'), _('You can not modify the company of this journal as its related record exist in journal items'))
718 return super(account_journal, self).write(cr, uid, ids, vals, context=context)
719
720 def create_sequence(self, cr, uid, vals, context=None):
721 """ Create new no_gap entry sequence for every new Joural
722 """
723 # in account.journal code is actually the prefix of the sequence
724 # whereas ir.sequence code is a key to lookup global sequences.
725 prefix = vals['code'].upper()
726
727 seq = {
728 'name': vals['name'],
729 'implementation':'no_gap',
730 'prefix': prefix + "/%(year)s/",
731 'padding': 4,
732 'number_increment': 1
733 }
734 if 'company_id' in vals:
735 seq['company_id'] = vals['company_id']
736 return self.pool.get('ir.sequence').create(cr, uid, seq)
737
738 def create(self, cr, uid, vals, context=None):
739 if not 'sequence_id' in vals or not vals['sequence_id']:
740 vals.update({'sequence_id': self.create_sequence(cr, uid, vals, context)})
741 return super(account_journal, self).create(cr, uid, vals, context)
742
743 def name_get(self, cr, user, ids, context=None):
744 """
745 Returns a list of tupples containing id, name.
746 result format: {[(id, name), (id, name), ...]}
747
748 @param cr: A database cursor
749 @param user: ID of the user currently logged in
750 @param ids: list of ids for which name should be read
751 @param context: context arguments, like lang, time zone
752
753 @return: Returns a list of tupples containing id, name
754 """
755 result = self.browse(cr, user, ids, context=context)
756 res = []
757 for rs in result:
758 name = rs.name
759 if rs.currency:
760 name = "%s (%s)" % (rs.name, rs.currency.name)
761 res += [(rs.id, name)]
762 return res
763
764 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
765 if not args:
766 args = []
767 if context is None:
768 context = {}
769 ids = []
770 if context.get('journal_type', False):
771 args += [('type','=',context.get('journal_type'))]
772 if name:
773 ids = self.search(cr, user, [('code', 'ilike', name)]+ args, limit=limit, context=context)
774 if not ids:
775 ids = self.search(cr, user, [('name', 'ilike', name)]+ args, limit=limit, context=context)#fix it ilike should be replace with operator
776
777 return self.name_get(cr, user, ids, context=context)
778
779 def onchange_type(self, cr, uid, ids, type, currency, context=None):
780 obj_data = self.pool.get('ir.model.data')
781 user_pool = self.pool.get('res.users')
782
783 type_map = {
784 'sale':'account_sp_journal_view',
785 'sale_refund':'account_sp_refund_journal_view',
786 'purchase':'account_sp_journal_view',
787 'purchase_refund':'account_sp_refund_journal_view',
788 'cash':'account_journal_bank_view',
789 'bank':'account_journal_bank_view',
790 'general':'account_journal_view',
791 'situation':'account_journal_view'
792 }
793
794 res = {}
795 view_id = type_map.get(type, 'account_journal_view')
796 user = user_pool.browse(cr, uid, uid)
797 if type in ('cash', 'bank') and currency and user.company_id.currency_id.id != currency:
798 view_id = 'account_journal_bank_view_multi'
799 data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=',view_id)])
800 data = obj_data.browse(cr, uid, data_id[0], context=context)
801
802 res.update({
803 'centralisation':type == 'situation',
804 'view_id':data.res_id,
805 })
806 return {
807 'value':res
808 }
809
810account_journal()
811
812class account_fiscalyear(osv.osv):
813 _name = "account.fiscalyear"
814 _description = "Fiscal Year"
815 _columns = {
816 'name': fields.char('Fiscal Year', size=64, required=True),
817 'code': fields.char('Code', size=6, required=True),
818 'company_id': fields.many2one('res.company', 'Company', required=True),
819 'date_start': fields.date('Start Date', required=True),
820 'date_stop': fields.date('End Date', required=True),
821 'period_ids': fields.one2many('account.period', 'fiscalyear_id', 'Periods'),
822 'state': fields.selection([('draft','Open'), ('done','Closed')], 'State', readonly=True),
823 }
824 _defaults = {
825 'state': 'draft',
826 'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
827 }
828 _order = "date_start"
829
830 def _check_fiscal_year(self, cr, uid, ids, context=None):
831 current_fiscal_yr = self.browse(cr, uid, ids, context=context)[0]
832 obj_fiscal_ids = self.search(cr, uid, [('company_id', '=', current_fiscal_yr.company_id.id)], context=context)
833 obj_fiscal_ids.remove(ids[0])
834 data_fiscal_yr = self.browse(cr, uid, obj_fiscal_ids, context=context)
835
836 for old_fy in data_fiscal_yr:
837 if old_fy.company_id.id == current_fiscal_yr['company_id'].id:
838 # Condition to check if the current fiscal year falls in between any previously defined fiscal year
839 if old_fy.date_start <= current_fiscal_yr['date_start'] <= old_fy.date_stop or \
840 old_fy.date_start <= current_fiscal_yr['date_stop'] <= old_fy.date_stop:
841 return False
842 return True
843
844 def _check_duration(self, cr, uid, ids, context=None):
845 obj_fy = self.browse(cr, uid, ids[0], context=context)
846 if obj_fy.date_stop < obj_fy.date_start:
847 return False
848 return True
849
850 _constraints = [
851 (_check_duration, 'Error! The start date of the fiscal year must be before his end date.', ['date_start','date_stop']),
852 (_check_fiscal_year, 'Error! You can not define overlapping fiscal years for the same company.',['date_start', 'date_stop'])
853 ]
854
855 def create_period3(self, cr, uid, ids, context=None):
856 return self.create_period(cr, uid, ids, context, 3)
857
858 def create_period(self, cr, uid, ids, context=None, interval=1):
859 period_obj = self.pool.get('account.period')
860 for fy in self.browse(cr, uid, ids, context=context):
861 ds = datetime.strptime(fy.date_start, '%Y-%m-%d')
862 period_obj.create(cr, uid, {
863 'name': _('Opening Period'),
864 'code': ds.strftime('00/%Y'),
865 'date_start': ds,
866 'date_stop': ds,
867 'special': True,
868 'fiscalyear_id': fy.id,
869 })
870 while ds.strftime('%Y-%m-%d') < fy.date_stop:
871 de = ds + relativedelta(months=interval, days=-1)
872
873 if de.strftime('%Y-%m-%d') > fy.date_stop:
874 de = datetime.strptime(fy.date_stop, '%Y-%m-%d')
875
876 period_obj.create(cr, uid, {
877 'name': ds.strftime('%m/%Y'),
878 'code': ds.strftime('%m/%Y'),
879 'date_start': ds.strftime('%Y-%m-%d'),
880 'date_stop': de.strftime('%Y-%m-%d'),
881 'fiscalyear_id': fy.id,
882 })
883 ds = ds + relativedelta(months=interval)
884 return True
885
886 def find(self, cr, uid, dt=None, exception=True, context=None):
887 if not dt:
888 dt = time.strftime('%Y-%m-%d')
889 ids = self.search(cr, uid, [('date_start', '<=', dt), ('date_stop', '>=', dt)])
890 if not ids:
891 if exception:
892 raise osv.except_osv(_('Error !'), _('No fiscal year defined for this date !\nPlease create one.'))
893 else:
894 return False
895 return ids[0]
896
897 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
898 if args is None:
899 args = []
900 if context is None:
901 context = {}
902 ids = []
903 if name:
904 ids = self.search(cr, user, [('code', 'ilike', name)]+ args, limit=limit)
905 if not ids:
906 ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit)
907 return self.name_get(cr, user, ids, context=context)
908
909account_fiscalyear()
910
911class account_period(osv.osv):
912 _name = "account.period"
913 _description = "Account period"
914 _columns = {
915 'name': fields.char('Period Name', size=64, required=True),
916 'code': fields.char('Code', size=12),
917 'special': fields.boolean('Opening/Closing Period', size=12,
918 help="These periods can overlap."),
919 'date_start': fields.date('Start of Period', required=True, states={'done':[('readonly',True)]}),
920 'date_stop': fields.date('End of Period', required=True, states={'done':[('readonly',True)]}),
921 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True),
922 'state': fields.selection([('draft','Open'), ('done','Closed')], 'State', readonly=True,
923 help='When monthly periods are created. The state is \'Draft\'. At the end of monthly period it is in \'Done\' state.'),
924 'company_id': fields.related('fiscalyear_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
925 }
926 _defaults = {
927 'state': 'draft',
928 }
929 _order = "date_start, special desc"
930 _sql_constraints = [
931 ('name_company_uniq', 'unique(name, company_id)', 'The name of the period must be unique per company!'),
932 ]
933
934 def _check_duration(self,cr,uid,ids,context=None):
935 obj_period = self.browse(cr, uid, ids[0], context=context)
936 if obj_period.date_stop < obj_period.date_start:
937 return False
938 return True
939
940 def _check_year_limit(self,cr,uid,ids,context=None):
941 for obj_period in self.browse(cr, uid, ids, context=context):
942 if obj_period.special:
943 continue
944
945 if obj_period.fiscalyear_id.date_stop < obj_period.date_stop or \
946 obj_period.fiscalyear_id.date_stop < obj_period.date_start or \
947 obj_period.fiscalyear_id.date_start > obj_period.date_start or \
948 obj_period.fiscalyear_id.date_start > obj_period.date_stop:
949 return False
950
951 pids = self.search(cr, uid, [('date_stop','>=',obj_period.date_start),('date_start','<=',obj_period.date_stop),('special','=',False),('id','<>',obj_period.id)])
952 for period in self.browse(cr, uid, pids):
953 if period.fiscalyear_id.company_id.id==obj_period.fiscalyear_id.company_id.id:
954 return False
955 return True
956
957 _constraints = [
958 (_check_duration, 'Error ! The duration of the Period(s) is/are invalid. ', ['date_stop']),
959 (_check_year_limit, 'Invalid period ! Some periods overlap or the date period is not in the scope of the fiscal year. ', ['date_stop'])
960 ]
961
962 def next(self, cr, uid, period, step, context=None):
963 ids = self.search(cr, uid, [('date_start','>',period.date_start)])
964 if len(ids)>=step:
965 return ids[step-1]
966 return False
967
968 def find(self, cr, uid, dt=None, context=None):
969 if not dt:
970 dt = time.strftime('%Y-%m-%d')
971#CHECKME: shouldn't we check the state of the period?
972 ids = self.search(cr, uid, [('date_start','<=',dt),('date_stop','>=',dt)])
973 if not ids:
974 raise osv.except_osv(_('Error !'), _('No period defined for this date: %s !\nPlease create one.')%dt)
975 return ids
976
977 def action_draft(self, cr, uid, ids, *args):
978 mode = 'draft'
979 cr.execute('update account_journal_period set state=%s where period_id in %s', (mode, tuple(ids),))
980 cr.execute('update account_period set state=%s where id in %s', (mode, tuple(ids),))
981 return True
982
983 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
984 if args is None:
985 args = []
986 if context is None:
987 context = {}
988 ids = []
989 if name:
990 ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit)
991 if not ids:
992 ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
993 return self.name_get(cr, user, ids, context=context)
994
995 def write(self, cr, uid, ids, vals, context=None):
996 if 'company_id' in vals:
997 move_lines = self.pool.get('account.move.line').search(cr, uid, [('period_id', 'in', ids)])
998 if move_lines:
999 raise osv.except_osv(_('Warning !'), _('You can not modify company of this period as some journal items exists.'))
1000 return super(account_period, self).write(cr, uid, ids, vals, context=context)
1001
1002 def build_ctx_periods(self, cr, uid, period_from_id, period_to_id):
1003 period_from = self.browse(cr, uid, period_from_id)
1004 period_date_start = period_from.date_start
1005 company1_id = period_from.company_id.id
1006 period_to = self.browse(cr, uid, period_to_id)
1007 period_date_stop = period_to.date_stop
1008 company2_id = period_to.company_id.id
1009 if company1_id != company2_id:
1010 raise osv.except_osv(_('Error'), _('You should have chosen periods that belongs to the same company'))
1011 if period_date_start > period_date_stop:
1012 raise osv.except_osv(_('Error'), _('Start period should be smaller then End period'))
1013 #for period from = january, we want to exclude the opening period (but it has same date_from, so we have to check if period_from is special or not to include that clause or not in the search).
1014 if period_from.special:
1015 return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id)])
1016 return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id), ('special', '=', False)])
1017
1018account_period()
1019
1020class account_journal_period(osv.osv):
1021 _name = "account.journal.period"
1022 _description = "Journal Period"
1023
1024 def _icon_get(self, cr, uid, ids, field_name, arg=None, context=None):
1025 result = {}.fromkeys(ids, 'STOCK_NEW')
1026 for r in self.read(cr, uid, ids, ['state']):
1027 result[r['id']] = {
1028 'draft': 'STOCK_NEW',
1029 'printed': 'STOCK_PRINT_PREVIEW',
1030 'done': 'STOCK_DIALOG_AUTHENTICATION',
1031 }.get(r['state'], 'STOCK_NEW')
1032 return result
1033
1034 _columns = {
1035 'name': fields.char('Journal-Period Name', size=64, required=True),
1036 'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade"),
1037 'period_id': fields.many2one('account.period', 'Period', required=True, ondelete="cascade"),
1038 'icon': fields.function(_icon_get, string='Icon', type='char', size=32),
1039 'active': fields.boolean('Active', required=True, help="If the active field is set to False, it will allow you to hide the journal period without removing it."),
1040 'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'State', required=True, readonly=True,
1041 help='When journal period is created. The state is \'Draft\'. If a report is printed it comes to \'Printed\' state. When all transactions are done, it comes in \'Done\' state.'),
1042 'fiscalyear_id': fields.related('period_id', 'fiscalyear_id', string='Fiscal Year', type='many2one', relation='account.fiscalyear'),
1043 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
1044 }
1045
1046 def _check(self, cr, uid, ids, context=None):
1047 for obj in self.browse(cr, uid, ids, context=context):
1048 cr.execute('select * from account_move_line where journal_id=%s and period_id=%s limit 1', (obj.journal_id.id, obj.period_id.id))
1049 res = cr.fetchall()
1050 if res:
1051 raise osv.except_osv(_('Error !'), _('You can not modify/delete a journal with entries for this period !'))
1052 return True
1053
1054 def write(self, cr, uid, ids, vals, context=None):
1055 self._check(cr, uid, ids, context=context)
1056 return super(account_journal_period, self).write(cr, uid, ids, vals, context=context)
1057
1058 def create(self, cr, uid, vals, context=None):
1059 period_id = vals.get('period_id',False)
1060 if period_id:
1061 period = self.pool.get('account.period').browse(cr, uid, period_id, context=context)
1062 vals['state']=period.state
1063 return super(account_journal_period, self).create(cr, uid, vals, context)
1064
1065 def unlink(self, cr, uid, ids, context=None):
1066 self._check(cr, uid, ids, context=context)
1067 return super(account_journal_period, self).unlink(cr, uid, ids, context=context)
1068
1069 _defaults = {
1070 'state': 'draft',
1071 'active': True,
1072 }
1073 _order = "period_id"
1074
1075account_journal_period()
1076
1077class account_fiscalyear(osv.osv):
1078 _inherit = "account.fiscalyear"
1079 _description = "Fiscal Year"
1080 _columns = {
1081 'end_journal_period_id':fields.many2one('account.journal.period','End of Year Entries Journal', readonly=True),
1082 }
1083
1084 def copy(self, cr, uid, id, default={}, context=None):
1085 default.update({
1086 'period_ids': [],
1087 'end_journal_period_id': False
1088 })
1089 return super(account_fiscalyear, self).copy(cr, uid, id, default=default, context=context)
1090
1091account_fiscalyear()
1092#----------------------------------------------------------
1093# Entries
1094#----------------------------------------------------------
1095class account_move(osv.osv):
1096 _name = "account.move"
1097 _description = "Account Entry"
1098 _order = 'id desc'
1099
1100 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
1101 """
1102 Returns a list of tupples containing id, name, as internally it is called {def name_get}
1103 result format: {[(id, name), (id, name), ...]}
1104
1105 @param cr: A database cursor
1106 @param user: ID of the user currently logged in
1107 @param name: name to search
1108 @param args: other arguments
1109 @param operator: default operator is 'ilike', it can be changed
1110 @param context: context arguments, like lang, time zone
1111 @param limit: Returns first 'n' ids of complete result, default is 80.
1112
1113 @return: Returns a list of tuples containing id and name
1114 """
1115
1116 if not args:
1117 args = []
1118 ids = []
1119 if name:
1120 ids += self.search(cr, user, [('name','ilike',name)]+args, limit=limit, context=context)
1121
1122 if not ids and name and type(name) == int:
1123 ids += self.search(cr, user, [('id','=',name)]+args, limit=limit, context=context)
1124
1125 if not ids:
1126 ids += self.search(cr, user, args, limit=limit, context=context)
1127
1128 return self.name_get(cr, user, ids, context=context)
1129
1130 def name_get(self, cursor, user, ids, context=None):
1131 if isinstance(ids, (int, long)):
1132 ids = [ids]
1133 if not ids:
1134 return []
1135 res = []
1136 data_move = self.pool.get('account.move').browse(cursor, user, ids, context=context)
1137 for move in data_move:
1138 if move.state=='draft':
1139 name = '*' + str(move.id)
1140 else:
1141 name = move.name
1142 res.append((move.id, name))
1143 return res
1144
1145 def _get_period(self, cr, uid, context=None):
1146 periods = self.pool.get('account.period').find(cr, uid)
1147 if periods:
1148 return periods[0]
1149 return False
1150
1151 def _amount_compute(self, cr, uid, ids, name, args, context, where =''):
1152 if not ids: return {}
1153 cr.execute( 'SELECT move_id, SUM(debit) '\
1154 'FROM account_move_line '\
1155 'WHERE move_id IN %s '\
1156 'GROUP BY move_id', (tuple(ids),))
1157 result = dict(cr.fetchall())
1158 for id in ids:
1159 result.setdefault(id, 0.0)
1160 return result
1161
1162 def _search_amount(self, cr, uid, obj, name, args, context):
1163 ids = set()
1164 for cond in args:
1165 amount = cond[2]
1166 if isinstance(cond[2],(list,tuple)):
1167 if cond[1] in ['in','not in']:
1168 amount = tuple(cond[2])
1169 else:
1170 continue
1171 else:
1172 if cond[1] in ['=like', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of']:
1173 continue
1174
1175 cr.execute("select move_id from account_move_line group by move_id having sum(debit) %s %%s" % (cond[1]),(amount,))
1176 res_ids = set(id[0] for id in cr.fetchall())
1177 ids = ids and (ids & res_ids) or res_ids
1178 if ids:
1179 return [('id', 'in', tuple(ids))]
1180 return [('id', '=', '0')]
1181
1182 _columns = {
1183 'name': fields.char('Number', size=64, required=True),
1184 'ref': fields.char('Reference', size=64),
1185 'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
1186 'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
1187 'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'State', required=True, readonly=True,
1188 help='All manually created new journal entry are usually in the state \'Unposted\', but you can set the option to skip that state on the related journal. In that case, they will be behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' state.'),
1189 'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
1190 'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
1191 'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
1192 'amount': fields.function(_amount_compute, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount),
1193 'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}, select=True),
1194 'narration':fields.text('Internal Note'),
1195 'company_id': fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
1196 }
1197 _defaults = {
1198 'name': '/',
1199 'state': 'draft',
1200 'period_id': _get_period,
1201 'date': lambda *a: time.strftime('%Y-%m-%d'),
1202 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
1203 }
1204
1205 def _check_centralisation(self, cursor, user, ids, context=None):
1206 for move in self.browse(cursor, user, ids, context=context):
1207 if move.journal_id.centralisation:
1208 move_ids = self.search(cursor, user, [
1209 ('period_id', '=', move.period_id.id),
1210 ('journal_id', '=', move.journal_id.id),
1211 ])
1212 if len(move_ids) > 1:
1213 return False
1214 return True
1215
1216 def _check_period_journal(self, cursor, user, ids, context=None):
1217 for move in self.browse(cursor, user, ids, context=context):
1218 for line in move.line_id:
1219 if line.period_id.id != move.period_id.id:
1220 return False
1221 if line.journal_id.id != move.journal_id.id:
1222 return False
1223 return True
1224
1225 _constraints = [
1226 (_check_centralisation,
1227 'You can not create more than one move per period on centralized journal',
1228 ['journal_id']),
1229 (_check_period_journal,
1230 'You can not create journal items on different periods/journals in the same journal entry',
1231 ['line_id']),
1232 ]
1233
1234 def post(self, cr, uid, ids, context=None):
1235 if context is None:
1236 context = {}
1237 invoice = context.get('invoice', False)
1238 valid_moves = self.validate(cr, uid, ids, context)
1239
1240 if not valid_moves:
1241 raise osv.except_osv(_('Integrity Error !'), _('You can not validate a non-balanced entry !\nMake sure you have configured payment terms properly !\nThe latest payment term line should be of the type "Balance" !'))
1242 obj_sequence = self.pool.get('ir.sequence')
1243 for move in self.browse(cr, uid, valid_moves, context=context):
1244 if move.name =='/':
1245 new_name = False
1246 journal = move.journal_id
1247
1248 if invoice and invoice.internal_number:
1249 new_name = invoice.internal_number
1250 else:
1251 if journal.sequence_id:
1252 c = {'fiscalyear_id': move.period_id.fiscalyear_id.id}
1253 new_name = obj_sequence.next_by_id(cr, uid, journal.sequence_id.id, c)
1254 else:
1255 raise osv.except_osv(_('Error'), _('No sequence defined on the journal !'))
1256
1257 if new_name:
1258 self.write(cr, uid, [move.id], {'name':new_name})
1259
1260 cr.execute('UPDATE account_move '\
1261 'SET state=%s '\
1262 'WHERE id IN %s',
1263 ('posted', tuple(valid_moves),))
1264 return True
1265
1266 def button_validate(self, cursor, user, ids, context=None):
1267 for move in self.browse(cursor, user, ids, context=context):
1268 top = None
1269 for line in move.line_id:
1270 account = line.account_id
1271 while account:
1272 account2 = account
1273 account = account.parent_id
1274 if not top:
1275 top = account2.id
1276 elif top<>account2.id:
1277 raise osv.except_osv(_('Error !'), _('You can not validate a journal entry unless all journal items belongs to the same chart of accounts !'))
1278 return self.post(cursor, user, ids, context=context)
1279
1280 def button_cancel(self, cr, uid, ids, context=None):
1281 for line in self.browse(cr, uid, ids, context=context):
1282 if not line.journal_id.update_posted:
1283 raise osv.except_osv(_('Error !'), _('You can not modify a posted entry of this journal !\nYou should set the journal to allow cancelling entries if you want to do that.'))
1284 if ids:
1285 cr.execute('UPDATE account_move '\
1286 'SET state=%s '\
1287 'WHERE id IN %s', ('draft', tuple(ids),))
1288 return True
1289
1290 def write(self, cr, uid, ids, vals, context=None):
1291 if context is None:
1292 context = {}
1293 c = context.copy()
1294 c['novalidate'] = True
1295 result = super(account_move, self).write(cr, uid, ids, vals, c)
1296 self.validate(cr, uid, ids, context=context)
1297 return result
1298
1299 #
1300 # TODO: Check if period is closed !
1301 #
1302 def create(self, cr, uid, vals, context=None):
1303 if context is None:
1304 context = {}
1305 if 'line_id' in vals and context.get('copy'):
1306 for l in vals['line_id']:
1307 if not l[0]:
1308 l[2].update({
1309 'reconcile_id':False,
1310 'reconcil_partial_id':False,
1311 'analytic_lines':False,
1312 'invoice':False,
1313 'ref':False,
1314 'balance':False,
1315 'account_tax_id':False,
1316 })
1317
1318 if 'journal_id' in vals and vals.get('journal_id', False):
1319 for l in vals['line_id']:
1320 if not l[0]:
1321 l[2]['journal_id'] = vals['journal_id']
1322 context['journal_id'] = vals['journal_id']
1323 if 'period_id' in vals:
1324 for l in vals['line_id']:
1325 if not l[0]:
1326 l[2]['period_id'] = vals['period_id']
1327 context['period_id'] = vals['period_id']
1328 else:
1329 default_period = self._get_period(cr, uid, context)
1330 for l in vals['line_id']:
1331 if not l[0]:
1332 l[2]['period_id'] = default_period
1333 context['period_id'] = default_period
1334
1335 if 'line_id' in vals:
1336 c = context.copy()
1337 c['novalidate'] = True
1338 result = super(account_move, self).create(cr, uid, vals, c)
1339 self.validate(cr, uid, [result], context)
1340 else:
1341 result = super(account_move, self).create(cr, uid, vals, context)
1342 return result
1343
1344 def copy(self, cr, uid, id, default={}, context=None):
1345 if context is None:
1346 context = {}
1347 default.update({
1348 'state':'draft',
1349 'name':'/',
1350 })
1351 context.update({
1352 'copy':True
1353 })
1354 return super(account_move, self).copy(cr, uid, id, default, context)
1355
1356 def unlink(self, cr, uid, ids, context=None, check=True):
1357 if context is None:
1358 context = {}
1359 toremove = []
1360 obj_move_line = self.pool.get('account.move.line')
1361 for move in self.browse(cr, uid, ids, context=context):
1362 if move['state'] != 'draft':
1363 raise osv.except_osv(_('UserError'),
1364 _('You can not delete a posted journal entry "%s"!') % \
1365 move['name'])
1366 line_ids = map(lambda x: x.id, move.line_id)
1367 context['journal_id'] = move.journal_id.id
1368 context['period_id'] = move.period_id.id
1369 obj_move_line._update_check(cr, uid, line_ids, context)
1370 obj_move_line.unlink(cr, uid, line_ids, context=context)
1371 toremove.append(move.id)
1372 result = super(account_move, self).unlink(cr, uid, toremove, context)
1373 return result
1374
1375 def _compute_balance(self, cr, uid, id, context=None):
1376 move = self.browse(cr, uid, id, context=context)
1377 amount = 0
1378 for line in move.line_id:
1379 amount+= (line.debit - line.credit)
1380 return amount
1381
1382 def _centralise(self, cr, uid, move, mode, context=None):
1383 assert mode in ('debit', 'credit'), 'Invalid Mode' #to prevent sql injection
1384 currency_obj = self.pool.get('res.currency')
1385 if context is None:
1386 context = {}
1387
1388 if mode=='credit':
1389 account_id = move.journal_id.default_debit_account_id.id
1390 mode2 = 'debit'
1391 if not account_id:
1392 raise osv.except_osv(_('UserError'),
1393 _('There is no default default debit account defined \n' \
1394 'on journal "%s"') % move.journal_id.name)
1395 else:
1396 account_id = move.journal_id.default_credit_account_id.id
1397 mode2 = 'credit'
1398 if not account_id:
1399 raise osv.except_osv(_('UserError'),
1400 _('There is no default default credit account defined \n' \
1401 'on journal "%s"') % move.journal_id.name)
1402
1403 # find the first line of this move with the current mode
1404 # or create it if it doesn't exist
1405 cr.execute('select id from account_move_line where move_id=%s and centralisation=%s limit 1', (move.id, mode))
1406 res = cr.fetchone()
1407 if res:
1408 line_id = res[0]
1409 else:
1410 context.update({'journal_id': move.journal_id.id, 'period_id': move.period_id.id})
1411 line_id = self.pool.get('account.move.line').create(cr, uid, {
1412 'name': _(mode.capitalize()+' Centralisation'),
1413 'centralisation': mode,
1414 'account_id': account_id,
1415 'move_id': move.id,
1416 'journal_id': move.journal_id.id,
1417 'period_id': move.period_id.id,
1418 'date': move.period_id.date_stop,
1419 'debit': 0.0,
1420 'credit': 0.0,
1421 }, context)
1422
1423 # find the first line of this move with the other mode
1424 # so that we can exclude it from our calculation
1425 cr.execute('select id from account_move_line where move_id=%s and centralisation=%s limit 1', (move.id, mode2))
1426 res = cr.fetchone()
1427 if res:
1428 line_id2 = res[0]
1429 else:
1430 line_id2 = 0
1431
1432 cr.execute('SELECT SUM(%s) FROM account_move_line WHERE move_id=%%s AND id!=%%s' % (mode,), (move.id, line_id2))
1433 result = cr.fetchone()[0] or 0.0
1434 cr.execute('update account_move_line set '+mode2+'=%s where id=%s', (result, line_id))
1435
1436 #adjust also the amount in currency if needed
1437 cr.execute("select currency_id, sum(amount_currency) as amount_currency from account_move_line where move_id = %s and currency_id is not null group by currency_id", (move.id,))
1438 for row in cr.dictfetchall():
1439 currency_id = currency_obj.browse(cr, uid, row['currency_id'], context=context)
1440 if not currency_obj.is_zero(cr, uid, currency_id, row['amount_currency']):
1441 amount_currency = row['amount_currency'] * -1
1442 account_id = amount_currency > 0 and move.journal_id.default_debit_account_id.id or move.journal_id.default_credit_account_id.id
1443 cr.execute('select id from account_move_line where move_id=%s and centralisation=\'currency\' and currency_id = %slimit 1', (move.id, row['currency_id']))
1444 res = cr.fetchone()
1445 if res:
1446 cr.execute('update account_move_line set amount_currency=%s , account_id=%s where id=%s', (amount_currency, account_id, res[0]))
1447 else:
1448 context.update({'journal_id': move.journal_id.id, 'period_id': move.period_id.id})
1449 line_id = self.pool.get('account.move.line').create(cr, uid, {
1450 'name': _('Currency Adjustment'),
1451 'centralisation': 'currency',
1452 'account_id': account_id,
1453 'move_id': move.id,
1454 'journal_id': move.journal_id.id,
1455 'period_id': move.period_id.id,
1456 'date': move.period_id.date_stop,
1457 'debit': 0.0,
1458 'credit': 0.0,
1459 'currency_id': row['currency_id'],
1460 'amount_currency': amount_currency,
1461 }, context)
1462
1463 return True
1464
1465 #
1466 # Validate a balanced move. If it is a centralised journal, create a move.
1467 #
1468 def validate(self, cr, uid, ids, context=None):
1469 if context and ('__last_update' in context):
1470 del context['__last_update']
1471
1472 valid_moves = [] #Maintains a list of moves which can be responsible to create analytic entries
1473 obj_analytic_line = self.pool.get('account.analytic.line')
1474 obj_move_line = self.pool.get('account.move.line')
1475 for move in self.browse(cr, uid, ids, context):
1476 # Unlink old analytic lines on move_lines
1477 for obj_line in move.line_id:
1478 for obj in obj_line.analytic_lines:
1479 obj_analytic_line.unlink(cr,uid,obj.id)
1480
1481 journal = move.journal_id
1482 amount = 0
1483 line_ids = []
1484 line_draft_ids = []
1485 company_id = None
1486 for line in move.line_id:
1487 amount += line.debit - line.credit
1488 line_ids.append(line.id)
1489 if line.state=='draft':
1490 line_draft_ids.append(line.id)
1491
1492 if not company_id:
1493 company_id = line.account_id.company_id.id
1494 if not company_id == line.account_id.company_id.id:
1495 raise osv.except_osv(_('Error'), _("Couldn't create move between different companies"))
1496
1497 if line.account_id.currency_id and line.currency_id:
1498 if line.account_id.currency_id.id != line.currency_id.id and (line.account_id.currency_id.id != line.account_id.company_id.currency_id.id):
1499 raise osv.except_osv(_('Error'), _("""Couldn't create move with currency different from the secondary currency of the account "%s - %s". Clear the secondary currency field of the account definition if you want to accept all currencies.""") % (line.account_id.code, line.account_id.name))
1500
1501 if abs(amount) < 10 ** -4:
1502 # If the move is balanced
1503 # Add to the list of valid moves
1504 # (analytic lines will be created later for valid moves)
1505 valid_moves.append(move)
1506
1507 # Check whether the move lines are confirmed
1508
1509 if not line_draft_ids:
1510 continue
1511 # Update the move lines (set them as valid)
1512
1513 obj_move_line.write(cr, uid, line_draft_ids, {
1514 'journal_id': move.journal_id.id,
1515 'period_id': move.period_id.id,
1516 'state': 'valid'
1517 }, context, check=False)
1518
1519 account = {}
1520 account2 = {}
1521
1522 if journal.type in ('purchase','sale'):
1523 for line in move.line_id:
1524 code = amount = 0
1525 key = (line.account_id.id, line.tax_code_id.id)
1526 if key in account2:
1527 code = account2[key][0]
1528 amount = account2[key][1] * (line.debit + line.credit)
1529 elif line.account_id.id in account:
1530 code = account[line.account_id.id][0]
1531 amount = account[line.account_id.id][1] * (line.debit + line.credit)
1532 if (code or amount) and not (line.tax_code_id or line.tax_amount):
1533 obj_move_line.write(cr, uid, [line.id], {
1534 'tax_code_id': code,
1535 'tax_amount': amount
1536 }, context, check=False)
1537 elif journal.centralisation:
1538 # If the move is not balanced, it must be centralised...
1539
1540 # Add to the list of valid moves
1541 # (analytic lines will be created later for valid moves)
1542 valid_moves.append(move)
1543
1544 #
1545 # Update the move lines (set them as valid)
1546 #
1547 self._centralise(cr, uid, move, 'debit', context=context)
1548 self._centralise(cr, uid, move, 'credit', context=context)
1549 obj_move_line.write(cr, uid, line_draft_ids, {
1550 'state': 'valid'
1551 }, context, check=False)
1552 else:
1553 # We can't validate it (it's unbalanced)
1554 # Setting the lines as draft
1555 obj_move_line.write(cr, uid, line_ids, {
1556 'journal_id': move.journal_id.id,
1557 'period_id': move.period_id.id,
1558 'state': 'draft'
1559 }, context, check=False)
1560 # Create analytic lines for the valid moves
1561 for record in valid_moves:
1562 obj_move_line.create_analytic_lines(cr, uid, [line.id for line in record.line_id], context)
1563
1564 valid_moves = [move.id for move in valid_moves]
1565 return len(valid_moves) > 0 and valid_moves or False
1566
1567account_move()
1568
1569class account_move_reconcile(osv.osv):
1570 _name = "account.move.reconcile"
1571 _description = "Account Reconciliation"
1572 _columns = {
1573 'name': fields.char('Name', size=64, required=True),
1574 'type': fields.char('Type', size=16, required=True),
1575 'line_id': fields.one2many('account.move.line', 'reconcile_id', 'Entry Lines'),
1576 'line_partial_ids': fields.one2many('account.move.line', 'reconcile_partial_id', 'Partial Entry lines'),
1577 'create_date': fields.date('Creation date', readonly=True),
1578 }
1579 _defaults = {
1580 'name': lambda self,cr,uid,ctx={}: self.pool.get('ir.sequence').get(cr, uid, 'account.reconcile') or '/',
1581 }
1582 def reconcile_partial_check(self, cr, uid, ids, type='auto', context=None):
1583 total = 0.0
1584 for rec in self.browse(cr, uid, ids, context=context):
1585 for line in rec.line_partial_ids:
1586 total += (line.debit or 0.0) - (line.credit or 0.0)
1587 if not total:
1588 self.pool.get('account.move.line').write(cr, uid,
1589 map(lambda x: x.id, rec.line_partial_ids),
1590 {'reconcile_id': rec.id }
1591 )
1592 return True
1593
1594 def name_get(self, cr, uid, ids, context=None):
1595 if not ids:
1596 return []
1597 result = []
1598 for r in self.browse(cr, uid, ids, context=context):
1599 total = reduce(lambda y,t: (t.debit or 0.0) - (t.credit or 0.0) + y, r.line_partial_ids, 0.0)
1600 if total:
1601 name = '%s (%.2f)' % (r.name, total)
1602 result.append((r.id,name))
1603 else:
1604 result.append((r.id,r.name))
1605 return result
1606
1607account_move_reconcile()
1608
1609#----------------------------------------------------------
1610# Tax
1611#----------------------------------------------------------
1612"""
1613a documenter
1614child_depend: la taxe depend des taxes filles
1615"""
1616class account_tax_code(osv.osv):
1617 """
1618 A code for the tax object.
1619
1620 This code is used for some tax declarations.
1621 """
1622 def _sum(self, cr, uid, ids, name, args, context, where ='', where_params=()):
1623 parent_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)]))
1624 if context.get('based_on', 'invoices') == 'payments':
1625 cr.execute('SELECT line.tax_code_id, sum(line.tax_amount) \
1626 FROM account_move_line AS line, \
1627 account_move AS move \
1628 LEFT JOIN account_invoice invoice ON \
1629 (invoice.move_id = move.id) \
1630 WHERE line.tax_code_id IN %s '+where+' \
1631 AND move.id = line.move_id \
1632 AND ((invoice.state = \'paid\') \
1633 OR (invoice.id IS NULL)) \
1634 GROUP BY line.tax_code_id',
1635 (parent_ids,) + where_params)
1636 else:
1637 cr.execute('SELECT line.tax_code_id, sum(line.tax_amount) \
1638 FROM account_move_line AS line, \
1639 account_move AS move \
1640 WHERE line.tax_code_id IN %s '+where+' \
1641 AND move.id = line.move_id \
1642 GROUP BY line.tax_code_id',
1643 (parent_ids,) + where_params)
1644 res=dict(cr.fetchall())
1645 obj_precision = self.pool.get('decimal.precision')
1646 res2 = {}
1647 for record in self.browse(cr, uid, ids, context=context):
1648 def _rec_get(record):
1649 amount = res.get(record.id, 0.0)
1650 for rec in record.child_ids:
1651 amount += _rec_get(rec) * rec.sign
1652 return amount
1653 res2[record.id] = round(_rec_get(record), obj_precision.precision_get(cr, uid, 'Account'))
1654 return res2
1655
1656 def _sum_year(self, cr, uid, ids, name, args, context=None):
1657 if context is None:
1658 context = {}
1659 move_state = ('posted', )
1660 if context.get('state', 'all') == 'all':
1661 move_state = ('draft', 'posted', )
1662 if context.get('fiscalyear_id', False):
1663 fiscalyear_id = context['fiscalyear_id']
1664 else:
1665 fiscalyear_id = self.pool.get('account.fiscalyear').find(cr, uid, exception=False)
1666 where = ''
1667 where_params = ()
1668 if fiscalyear_id:
1669 pids = map(lambda x: str(x.id), self.pool.get('account.fiscalyear').browse(cr, uid, fiscalyear_id).period_ids)
1670 if pids:
1671 where = ' AND line.period_id IN %s AND move.state IN %s '
1672 where_params = (tuple(pids), move_state)
1673 return self._sum(cr, uid, ids, name, args, context,
1674 where=where, where_params=where_params)
1675
1676 def _sum_period(self, cr, uid, ids, name, args, context):
1677 if context is None:
1678 context = {}
1679 move_state = ('posted', )
1680 if context.get('state', False) == 'all':
1681 move_state = ('draft', 'posted', )
1682 if context.get('period_id', False):
1683 period_id = context['period_id']
1684 else:
1685 period_id = self.pool.get('account.period').find(cr, uid)
1686 if not period_id:
1687 return dict.fromkeys(ids, 0.0)
1688 period_id = period_id[0]
1689 return self._sum(cr, uid, ids, name, args, context,
1690 where=' AND line.period_id=%s AND move.state IN %s', where_params=(period_id, move_state))
1691
1692 _name = 'account.tax.code'
1693 _description = 'Tax Code'
1694 _rec_name = 'code'
1695 _columns = {
1696 'name': fields.char('Tax Case Name', size=64, required=True, translate=True),
1697 'code': fields.char('Case Code', size=64),
1698 'info': fields.text('Description'),
1699 'sum': fields.function(_sum_year, string="Year Sum"),
1700 'sum_period': fields.function(_sum_period, string="Period Sum"),
1701 'parent_id': fields.many2one('account.tax.code', 'Parent Code', select=True),
1702 'child_ids': fields.one2many('account.tax.code', 'parent_id', 'Child Codes'),
1703 'line_ids': fields.one2many('account.move.line', 'tax_code_id', 'Lines'),
1704 'company_id': fields.many2one('res.company', 'Company', required=True),
1705 'sign': fields.float('Coefficent for parent', required=True, help='You can specify here the coefficient that will be used when consolidating the amount of this case into its parent. For example, set 1/-1 if you want to add/substract it.'),
1706 'notprintable':fields.boolean("Not Printable in Invoice", help="Check this box if you don't want any VAT related to this Tax Code to appear on invoices"),
1707 }
1708
1709 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
1710 if not args:
1711 args = []
1712 if context is None:
1713 context = {}
1714 ids = self.search(cr, user, ['|',('name',operator,name),('code',operator,name)] + args, limit=limit, context=context)
1715 return self.name_get(cr, user, ids, context)
1716
1717 def name_get(self, cr, uid, ids, context=None):
1718 if isinstance(ids, (int, long)):
1719 ids = [ids]
1720 if not ids:
1721 return []
1722 if isinstance(ids, (int, long)):
1723 ids = [ids]
1724 reads = self.read(cr, uid, ids, ['name','code'], context, load='_classic_write')
1725 return [(x['id'], (x['code'] and (x['code'] + ' - ') or '') + x['name']) \
1726 for x in reads]
1727
1728 def _default_company(self, cr, uid, context=None):
1729 user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
1730 if user.company_id:
1731 return user.company_id.id
1732 return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
1733 _defaults = {
1734 'company_id': _default_company,
1735 'sign': 1.0,
1736 'notprintable': False,
1737 }
1738
1739 def copy(self, cr, uid, id, default=None, context=None):
1740 if default is None:
1741 default = {}
1742 default = default.copy()
1743 default.update({'line_ids': []})
1744 return super(account_tax_code, self).copy(cr, uid, id, default, context)
1745
1746 _check_recursion = check_cycle
1747 _constraints = [
1748 (_check_recursion, 'Error ! You can not create recursive accounts.', ['parent_id'])
1749 ]
1750 _order = 'code'
1751
1752account_tax_code()
1753
1754class account_tax(osv.osv):
1755 """
1756 A tax object.
1757
1758 Type: percent, fixed, none, code
1759 PERCENT: tax = price * amount
1760 FIXED: tax = price + amount
1761 NONE: no tax line
1762 CODE: execute python code. localcontext = {'price_unit':pu, 'address':address_object}
1763 return result in the context
1764 Ex: result=round(price_unit*0.21,4)
1765 """
1766
1767 def get_precision_tax():
1768 def change_digit_tax(cr):
1769 res = pooler.get_pool(cr.dbname).get('decimal.precision').precision_get(cr, 1, 'Account')
1770 return (16, res+2)
1771 return change_digit_tax
1772
1773 _name = 'account.tax'
1774 _description = 'Tax'
1775 _columns = {
1776 'name': fields.char('Tax Name', size=64, required=True, translate=True, help="This name will be displayed on reports"),
1777 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the tax lines from the lowest sequences to the higher ones. The order is important if you have a tax with several tax children. In this case, the evaluation order is important."),
1778 'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For taxes of type percentage, enter % ratio between 0-1."),
1779 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the tax without removing it."),
1780 'type': fields.selection( [('percent','Percentage'), ('fixed','Fixed Amount'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True,
1781 help="The computation method for the tax amount."),
1782 'applicable_type': fields.selection( [('true','Always'), ('code','Given by Python Code')], 'Applicability', required=True,
1783 help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
1784 'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
1785 'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account'),
1786 'account_paid_id':fields.many2one('account.account', 'Refund Tax Account'),
1787 'parent_id':fields.many2one('account.tax', 'Parent Tax Account', select=True),
1788 'child_ids':fields.one2many('account.tax', 'parent_id', 'Child Tax Accounts'),
1789 'child_depend':fields.boolean('Tax on Children', help="Set if the tax computation is based on the computation of child taxes rather than on the total amount."),
1790 'python_compute':fields.text('Python Code'),
1791 'python_compute_inv':fields.text('Python Code (reverse)'),
1792 'python_applicable':fields.text('Python Code'),
1793
1794 #
1795 # Fields used for the VAT declaration
1796 #
1797 'base_code_id': fields.many2one('account.tax.code', 'Account Base Code', help="Use this code for the VAT declaration."),
1798 'tax_code_id': fields.many2one('account.tax.code', 'Account Tax Code', help="Use this code for the VAT declaration."),
1799 'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
1800 'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
1801
1802 # Same fields for refund invoices
1803
1804 'ref_base_code_id': fields.many2one('account.tax.code', 'Refund Base Code', help="Use this code for the VAT declaration."),
1805 'ref_tax_code_id': fields.many2one('account.tax.code', 'Refund Tax Code', help="Use this code for the VAT declaration."),
1806 'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
1807 'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
1808 'include_base_amount': fields.boolean('Included in base amount', help="Indicates if the amount of tax must be included in the base amount for the computation of the next taxes"),
1809 'company_id': fields.many2one('res.company', 'Company', required=True),
1810 'description': fields.char('Tax Code',size=32),
1811 'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
1812 'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Application', required=True)
1813
1814 }
1815 _sql_constraints = [
1816 ('name_company_uniq', 'unique(name, company_id)', 'Tax Name must be unique per company!'),
1817 ]
1818
1819 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
1820 """
1821 Returns a list of tupples containing id, name, as internally it is called {def name_get}
1822 result format: {[(id, name), (id, name), ...]}
1823
1824 @param cr: A database cursor
1825 @param user: ID of the user currently logged in
1826 @param name: name to search
1827 @param args: other arguments
1828 @param operator: default operator is 'ilike', it can be changed
1829 @param context: context arguments, like lang, time zone
1830 @param limit: Returns first 'n' ids of complete result, default is 80.
1831
1832 @return: Returns a list of tupples containing id and name
1833 """
1834 if not args:
1835 args = []
1836 if context is None:
1837 context = {}
1838 ids = []
1839 if name:
1840 ids = self.search(cr, user, [('description', '=', name)] + args, limit=limit, context=context)
1841 if not ids:
1842 ids = self.search(cr, user, [('name', operator, name)] + args, limit=limit, context=context)
1843 else:
1844 ids = self.search(cr, user, args, limit=limit, context=context or {})
1845 return self.name_get(cr, user, ids, context=context)
1846
1847 def write(self, cr, uid, ids, vals, context=None):
1848 if vals.get('type', False) and vals['type'] in ('none', 'code'):
1849 vals.update({'amount': 0.0})
1850 return super(account_tax, self).write(cr, uid, ids, vals, context=context)
1851
1852 def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
1853 journal_pool = self.pool.get('account.journal')
1854
1855 if context and context.has_key('type'):
1856 if context.get('type') in ('out_invoice','out_refund'):
1857 args += [('type_tax_use','in',['sale','all'])]
1858 elif context.get('type') in ('in_invoice','in_refund'):
1859 args += [('type_tax_use','in',['purchase','all'])]
1860
1861 if context and context.has_key('journal_id'):
1862 journal = journal_pool.browse(cr, uid, context.get('journal_id'))
1863 if journal.type in ('sale', 'purchase'):
1864 args += [('type_tax_use','in',[journal.type,'all'])]
1865
1866 return super(account_tax, self).search(cr, uid, args, offset, limit, order, context, count)
1867
1868 def name_get(self, cr, uid, ids, context=None):
1869 if not ids:
1870 return []
1871 res = []
1872 for record in self.read(cr, uid, ids, ['description','name'], context=context):
1873 name = record['description'] and record['description'] or record['name']
1874 res.append((record['id'],name ))
1875 return res
1876
1877 def _default_company(self, cr, uid, context=None):
1878 user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
1879 if user.company_id:
1880 return user.company_id.id
1881 return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
1882
1883 _defaults = {
1884 'python_compute': '''# price_unit\n# address: res.partner.address object or False\n# product: product.product object or None\n# partner: res.partner object or None\n\nresult = price_unit * 0.10''',
1885 'python_compute_inv': '''# price_unit\n# address: res.partner.address object or False\n# product: product.product object or False\n\nresult = price_unit * 0.10''',
1886 'applicable_type': 'true',
1887 'type': 'percent',
1888 'amount': 0,
1889 'price_include': 0,
1890 'active': 1,
1891 'type_tax_use': 'all',
1892 'sequence': 1,
1893 'ref_tax_sign': 1,
1894 'ref_base_sign': 1,
1895 'tax_sign': 1,
1896 'base_sign': 1,
1897 'include_base_amount': False,
1898 'company_id': _default_company,
1899 }
1900 _order = 'sequence'
1901
1902 def _applicable(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None):
1903 res = []
1904 obj_partener_address = self.pool.get('res.partner.address')
1905 for tax in taxes:
1906 if tax.applicable_type=='code':
1907 localdict = {'price_unit':price_unit, 'address':obj_partener_address.browse(cr, uid, address_id), 'product':product, 'partner':partner}
1908 exec tax.python_applicable in localdict
1909 if localdict.get('result', False):
1910 res.append(tax)
1911 else:
1912 res.append(tax)
1913 return res
1914
1915 def _unit_compute(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None, quantity=0):
1916 taxes = self._applicable(cr, uid, taxes, price_unit, address_id, product, partner)
1917 res = []
1918 cur_price_unit=price_unit
1919 obj_partener_address = self.pool.get('res.partner.address')
1920 for tax in taxes:
1921 # we compute the amount for the current tax object and append it to the result
1922 data = {'id':tax.id,
1923 'name':tax.description and tax.description + " - " + tax.name or tax.name,
1924 'account_collected_id':tax.account_collected_id.id,
1925 'account_paid_id':tax.account_paid_id.id,
1926 'base_code_id': tax.base_code_id.id,
1927 'ref_base_code_id': tax.ref_base_code_id.id,
1928 'sequence': tax.sequence,
1929 'base_sign': tax.base_sign,
1930 'tax_sign': tax.tax_sign,
1931 'ref_base_sign': tax.ref_base_sign,
1932 'ref_tax_sign': tax.ref_tax_sign,
1933 'price_unit': cur_price_unit,
1934 'tax_code_id': tax.tax_code_id.id,
1935 'ref_tax_code_id': tax.ref_tax_code_id.id,
1936 }
1937 res.append(data)
1938 if tax.type=='percent':
1939 amount = cur_price_unit * tax.amount
1940 data['amount'] = amount
1941
1942 elif tax.type=='fixed':
1943 data['amount'] = tax.amount
1944 data['tax_amount']=quantity
1945 # data['amount'] = quantity
1946 elif tax.type=='code':
1947 address = address_id and obj_partener_address.browse(cr, uid, address_id) or None
1948 localdict = {'price_unit':cur_price_unit, 'address':address, 'product':product, 'partner':partner}
1949 exec tax.python_compute in localdict
1950 amount = localdict['result']
1951 data['amount'] = amount
1952 elif tax.type=='balance':
1953 data['amount'] = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0)
1954 data['balance'] = cur_price_unit
1955
1956 amount2 = data.get('amount', 0.0)
1957 if tax.child_ids:
1958 if tax.child_depend:
1959 latest = res.pop()
1960 amount = amount2
1961 child_tax = self._unit_compute(cr, uid, tax.child_ids, amount, address_id, product, partner, quantity)
1962 res.extend(child_tax)
1963 if tax.child_depend:
1964 for r in res:
1965 for name in ('base','ref_base'):
1966 if latest[name+'_code_id'] and latest[name+'_sign'] and not r[name+'_code_id']:
1967 r[name+'_code_id'] = latest[name+'_code_id']
1968 r[name+'_sign'] = latest[name+'_sign']
1969 r['price_unit'] = latest['price_unit']
1970 latest[name+'_code_id'] = False
1971 for name in ('tax','ref_tax'):
1972 if latest[name+'_code_id'] and latest[name+'_sign'] and not r[name+'_code_id']:
1973 r[name+'_code_id'] = latest[name+'_code_id']
1974 r[name+'_sign'] = latest[name+'_sign']
1975 r['amount'] = data['amount']
1976 latest[name+'_code_id'] = False
1977 if tax.include_base_amount:
1978 cur_price_unit+=amount2
1979 return res
1980
1981 def compute_all(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
1982 """
1983 RETURN: {
1984 'total': 0.0, # Total without taxes
1985 'total_included: 0.0, # Total with taxes
1986 'taxes': [] # List of taxes, see compute for the format
1987 }
1988 """
1989 precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
1990 totalin = totalex = round(price_unit * quantity, precision)
1991 tin = []
1992 tex = []
1993 for tax in taxes:
1994 if tax.price_include:
1995 tin.append(tax)
1996 else:
1997 tex.append(tax)
1998 tin = self.compute_inv(cr, uid, tin, price_unit, quantity, address_id=address_id, product=product, partner=partner)
1999 for r in tin:
2000 totalex -= r.get('amount', 0.0)
2001 totlex_qty = 0.0
2002 try:
2003 totlex_qty = totalex/quantity
2004 except:
2005 pass
2006 tex = self._compute(cr, uid, tex, totlex_qty, quantity, address_id=address_id, product=product, partner=partner)
2007 for r in tex:
2008 totalin += r.get('amount', 0.0)
2009 return {
2010 'total': totalex,
2011 'total_included': totalin,
2012 'taxes': tin + tex
2013 }
2014
2015 def compute(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
2016 logger = netsvc.Logger()
2017 logger.notifyChannel("warning", netsvc.LOG_WARNING,
2018 "Deprecated, use compute_all(...)['taxes'] instead of compute(...) to manage prices with tax included")
2019 return self._compute(cr, uid, taxes, price_unit, quantity, address_id, product, partner)
2020
2021 def _compute(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
2022 """
2023 Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
2024
2025 RETURN:
2026 [ tax ]
2027 tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
2028 one tax for each tax id in IDS and their children
2029 """
2030 res = self._unit_compute(cr, uid, taxes, price_unit, address_id, product, partner, quantity)
2031 total = 0.0
2032 precision_pool = self.pool.get('decimal.precision')
2033 for r in res:
2034 if r.get('balance',False):
2035 r['amount'] = round(r.get('balance', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account')) - total
2036 else:
2037 r['amount'] = round(r.get('amount', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account'))
2038 total += r['amount']
2039 return res
2040
2041 def _unit_compute_inv(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None):
2042 taxes = self._applicable(cr, uid, taxes, price_unit, address_id, product, partner)
2043 obj_partener_address = self.pool.get('res.partner.address')
2044 res = []
2045 taxes.reverse()
2046 cur_price_unit = price_unit
2047
2048 tax_parent_tot = 0.0
2049 for tax in taxes:
2050 if (tax.type=='percent') and not tax.include_base_amount:
2051 tax_parent_tot += tax.amount
2052
2053 for tax in taxes:
2054 if (tax.type=='fixed') and not tax.include_base_amount:
2055 cur_price_unit -= tax.amount
2056
2057 for tax in taxes:
2058 if tax.type=='percent':
2059 if tax.include_base_amount:
2060 amount = cur_price_unit - (cur_price_unit / (1 + tax.amount))
2061 else:
2062 amount = (cur_price_unit / (1 + tax_parent_tot)) * tax.amount
2063
2064 elif tax.type=='fixed':
2065 amount = tax.amount
2066
2067 elif tax.type=='code':
2068 address = address_id and obj_partener_address.browse(cr, uid, address_id) or None
2069 localdict = {'price_unit':cur_price_unit, 'address':address, 'product':product, 'partner':partner}
2070 exec tax.python_compute_inv in localdict
2071 amount = localdict['result']
2072 elif tax.type=='balance':
2073 amount = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0)
2074
2075 if tax.include_base_amount:
2076 cur_price_unit -= amount
2077 todo = 0
2078 else:
2079 todo = 1
2080 res.append({
2081 'id': tax.id,
2082 'todo': todo,
2083 'name': tax.name,
2084 'amount': amount,
2085 'account_collected_id': tax.account_collected_id.id,
2086 'account_paid_id': tax.account_paid_id.id,
2087 'base_code_id': tax.base_code_id.id,
2088 'ref_base_code_id': tax.ref_base_code_id.id,
2089 'sequence': tax.sequence,
2090 'base_sign': tax.base_sign,
2091 'tax_sign': tax.tax_sign,
2092 'ref_base_sign': tax.ref_base_sign,
2093 'ref_tax_sign': tax.ref_tax_sign,
2094 'price_unit': cur_price_unit,
2095 'tax_code_id': tax.tax_code_id.id,
2096 'ref_tax_code_id': tax.ref_tax_code_id.id,
2097 })
2098 if tax.child_ids:
2099 if tax.child_depend:
2100 del res[-1]
2101 amount = price_unit
2102
2103 parent_tax = self._unit_compute_inv(cr, uid, tax.child_ids, amount, address_id, product, partner)
2104 res.extend(parent_tax)
2105
2106 total = 0.0
2107 for r in res:
2108 if r['todo']:
2109 total += r['amount']
2110 for r in res:
2111 r['price_unit'] -= total
2112 r['todo'] = 0
2113 return res
2114
2115 def compute_inv(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
2116 """
2117 Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
2118 Price Unit is a VAT included price
2119
2120 RETURN:
2121 [ tax ]
2122 tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
2123 one tax for each tax id in IDS and their children
2124 """
2125 res = self._unit_compute_inv(cr, uid, taxes, price_unit, address_id, product, partner=None)
2126 total = 0.0
2127 obj_precision = self.pool.get('decimal.precision')
2128 for r in res:
2129 prec = obj_precision.precision_get(cr, uid, 'Account')
2130 if r.get('balance',False):
2131 r['amount'] = round(r['balance'] * quantity, prec) - total
2132 else:
2133 r['amount'] = round(r['amount'] * quantity, prec)
2134 total += r['amount']
2135 return res
2136
2137account_tax()
2138
2139# ---------------------------------------------------------
2140# Account Entries Models
2141# ---------------------------------------------------------
2142
2143class account_model(osv.osv):
2144 _name = "account.model"
2145 _description = "Account Model"
2146 _columns = {
2147 'name': fields.char('Model Name', size=64, required=True, help="This is a model for recurring accounting entries"),
2148 'journal_id': fields.many2one('account.journal', 'Journal', required=True),
2149 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
2150 'lines_id': fields.one2many('account.model.line', 'model_id', 'Model Entries'),
2151 'legend': fields.text('Legend', readonly=True, size=100),
2152 }
2153
2154 _defaults = {
2155 'legend': lambda self, cr, uid, context:_('You can specify year, month and date in the name of the model using the following labels:\n\n%(year)s: To Specify Year \n%(month)s: To Specify Month \n%(date)s: Current Date\n\ne.g. My model on %(date)s'),
2156 }
2157 def generate(self, cr, uid, ids, datas={}, context=None):
2158 move_ids = []
2159 entry = {}
2160 account_move_obj = self.pool.get('account.move')
2161 account_move_line_obj = self.pool.get('account.move.line')
2162 pt_obj = self.pool.get('account.payment.term')
2163
2164 if context is None:
2165 context = {}
2166
2167 if datas.get('date', False):
2168 context.update({'date': datas['date']})
2169
2170 period_id = self.pool.get('account.period').find(cr, uid, dt=context.get('date', False))
2171 if not period_id:
2172 raise osv.except_osv(_('No period found !'), _('Unable to find a valid period !'))
2173 period_id = period_id[0]
2174
2175 for model in self.browse(cr, uid, ids, context=context):
2176 try:
2177 entry['name'] = model.name%{'year':time.strftime('%Y'), 'month':time.strftime('%m'), 'date':time.strftime('%Y-%m')}
2178 except:
2179 raise osv.except_osv(_('Wrong model !'), _('You have a wrong expression "%(...)s" in your model !'))
2180
2181 move_id = account_move_obj.create(cr, uid, {
2182 'ref': entry['name'],
2183 'period_id': period_id,
2184 'journal_id': model.journal_id.id,
2185 'date': context.get('date',time.strftime('%Y-%m-%d'))
2186 })
2187 move_ids.append(move_id)
2188 for line in model.lines_id:
2189 analytic_account_id = False
2190 if line.analytic_account_id:
2191 if not model.journal_id.analytic_journal_id:
2192 raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (model.journal_id.name,))
2193 analytic_account_id = line.analytic_account_id.id
2194 val = {
2195 'move_id': move_id,
2196 'journal_id': model.journal_id.id,
2197 'period_id': period_id,
2198 'analytic_account_id': analytic_account_id
2199 }
2200
2201 date_maturity = time.strftime('%Y-%m-%d')
2202 if line.date_maturity == 'partner':
2203 if not line.partner_id:
2204 raise osv.except_osv(_('Error !'), _("Maturity date of entry line generated by model line '%s' of model '%s' is based on partner payment term!" \
2205 "\nPlease define partner on it!")%(line.name, model.name))
2206 if line.partner_id.property_payment_term:
2207 payment_term_id = line.partner_id.property_payment_term.id
2208 pterm_list = pt_obj.compute(cr, uid, payment_term_id, value=1, date_ref=date_maturity)
2209 if pterm_list:
2210 pterm_list = [l[0] for l in pterm_list]
2211 pterm_list.sort()
2212 date_maturity = pterm_list[-1]
2213
2214 val.update({
2215 'name': line.name,
2216 'quantity': line.quantity,
2217 'debit': line.debit,
2218 'credit': line.credit,
2219 'account_id': line.account_id.id,
2220 'move_id': move_id,
2221 'partner_id': line.partner_id.id,
2222 'date': context.get('date',time.strftime('%Y-%m-%d')),
2223 'date_maturity': date_maturity
2224 })
2225 c = context.copy()
2226 c.update({'journal_id': model.journal_id.id,'period_id': period_id})
2227 account_move_line_obj.create(cr, uid, val, context=c)
2228
2229 return move_ids
2230
2231account_model()
2232
2233class account_model_line(osv.osv):
2234 _name = "account.model.line"
2235 _description = "Account Model Entries"
2236 _columns = {
2237 'name': fields.char('Name', size=64, required=True),
2238 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the resources from lower sequences to higher ones."),
2239 'quantity': fields.float('Quantity', digits_compute=dp.get_precision('Account'), help="The optional quantity on entries."),
2240 'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')),
2241 'credit': fields.float('Credit', digits_compute=dp.get_precision('Account')),
2242 'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade"),
2243 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', ondelete="cascade"),
2244 'model_id': fields.many2one('account.model', 'Model', required=True, ondelete="cascade", select=True),
2245 'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency."),
2246 'currency_id': fields.many2one('res.currency', 'Currency'),
2247 'partner_id': fields.many2one('res.partner', 'Partner'),
2248 'date_maturity': fields.selection([('today','Date of the day'), ('partner','Partner Payment Term')], 'Maturity Date', help="The maturity date of the generated entries for this model. You can choose between the creation date or the creation date of the entries plus the partner payment terms."),
2249 }
2250 _order = 'sequence'
2251 _sql_constraints = [
2252 ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in model, they must be positive!'),
2253 ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in model, they must be positive!'),
2254 ]
2255account_model_line()
2256
2257# ---------------------------------------------------------
2258# Account Subscription
2259# ---------------------------------------------------------
2260
2261
2262class account_subscription(osv.osv):
2263 _name = "account.subscription"
2264 _description = "Account Subscription"
2265 _columns = {
2266 'name': fields.char('Name', size=64, required=True),
2267 'ref': fields.char('Reference', size=16),
2268 'model_id': fields.many2one('account.model', 'Model', required=True),
2269 'date_start': fields.date('Start Date', required=True),
2270 'period_total': fields.integer('Number of Periods', required=True),
2271 'period_nbr': fields.integer('Period', required=True),
2272 'period_type': fields.selection([('day','days'),('month','month'),('year','year')], 'Period Type', required=True),
2273 'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'State', required=True, readonly=True),
2274 'lines_id': fields.one2many('account.subscription.line', 'subscription_id', 'Subscription Lines')
2275 }
2276 _defaults = {
2277 'date_start': lambda *a: time.strftime('%Y-%m-%d'),
2278 'period_type': 'month',
2279 'period_total': 12,
2280 'period_nbr': 1,
2281 'state': 'draft',
2282 }
2283 def state_draft(self, cr, uid, ids, context=None):
2284 self.write(cr, uid, ids, {'state':'draft'})
2285 return False
2286
2287 def check(self, cr, uid, ids, context=None):
2288 todone = []
2289 for sub in self.browse(cr, uid, ids, context=context):
2290 ok = True
2291 for line in sub.lines_id:
2292 if not line.move_id.id:
2293 ok = False
2294 break
2295 if ok:
2296 todone.append(sub.id)
2297 if todone:
2298 self.write(cr, uid, todone, {'state':'done'})
2299 return False
2300
2301 def remove_line(self, cr, uid, ids, context=None):
2302 toremove = []
2303 for sub in self.browse(cr, uid, ids, context=context):
2304 for line in sub.lines_id:
2305 if not line.move_id.id:
2306 toremove.append(line.id)
2307 if toremove:
2308 self.pool.get('account.subscription.line').unlink(cr, uid, toremove)
2309 self.write(cr, uid, ids, {'state':'draft'})
2310 return False
2311
2312 def compute(self, cr, uid, ids, context=None):
2313 for sub in self.browse(cr, uid, ids, context=context):
2314 ds = sub.date_start
2315 for i in range(sub.period_total):
2316 self.pool.get('account.subscription.line').create(cr, uid, {
2317 'date': ds,
2318 'subscription_id': sub.id,
2319 })
2320 if sub.period_type=='day':
2321 ds = (datetime.strptime(ds, '%Y-%m-%d') + relativedelta(days=sub.period_nbr)).strftime('%Y-%m-%d')
2322 if sub.period_type=='month':
2323 ds = (datetime.strptime(ds, '%Y-%m-%d') + relativedelta(months=sub.period_nbr)).strftime('%Y-%m-%d')
2324 if sub.period_type=='year':
2325 ds = (datetime.strptime(ds, '%Y-%m-%d') + relativedelta(years=sub.period_nbr)).strftime('%Y-%m-%d')
2326 self.write(cr, uid, ids, {'state':'running'})
2327 return True
2328
2329account_subscription()
2330
2331class account_subscription_line(osv.osv):
2332 _name = "account.subscription.line"
2333 _description = "Account Subscription Line"
2334 _columns = {
2335 'subscription_id': fields.many2one('account.subscription', 'Subscription', required=True, select=True),
2336 'date': fields.date('Date', required=True),
2337 'move_id': fields.many2one('account.move', 'Entry'),
2338 }
2339
2340 def move_create(self, cr, uid, ids, context=None):
2341 tocheck = {}
2342 all_moves = []
2343 obj_model = self.pool.get('account.model')
2344 for line in self.browse(cr, uid, ids, context=context):
2345 datas = {
2346 'date': line.date,
2347 }
2348 move_ids = obj_model.generate(cr, uid, [line.subscription_id.model_id.id], datas, context)
2349 tocheck[line.subscription_id.id] = True
2350 self.write(cr, uid, [line.id], {'move_id':move_ids[0]})
2351 all_moves.extend(move_ids)
2352 if tocheck:
2353 self.pool.get('account.subscription').check(cr, uid, tocheck.keys(), context)
2354 return all_moves
2355
2356 _rec_name = 'date'
2357
2358account_subscription_line()
2359
2360# ---------------------------------------------------------------
2361# Account Templates: Account, Tax, Tax Code and chart. + Wizard
2362# ---------------------------------------------------------------
2363
2364class account_tax_template(osv.osv):
2365 _name = 'account.tax.template'
2366account_tax_template()
2367
2368class account_account_template(osv.osv):
2369 _order = "code"
2370 _name = "account.account.template"
2371 _description ='Templates for Accounts'
2372
2373 _columns = {
2374 'name': fields.char('Name', size=128, required=True, select=True),
2375 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
2376 'code': fields.char('Code', size=64, select=1),
2377 'type': fields.selection([
2378 ('receivable','Receivable'),
2379 ('payable','Payable'),
2380 ('view','View'),
2381 ('consolidation','Consolidation'),
2382 ('liquidity','Liquidity'),
2383 ('other','Regular'),
2384 ('closed','Closed'),
2385 ], 'Internal Type', required=True,help="This type is used to differentiate types with "\
2386 "special effects in OpenERP: view can not have entries, consolidation are accounts that "\
2387 "can have children accounts for multi-company consolidations, payable/receivable are for "\
2388 "partners accounts (for debit/credit computations), closed for depreciated accounts."),
2389 'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
2390 help="These types are defined according to your country. The type contains more information "\
2391 "about the account and its specificities."),
2392 'reconcile': fields.boolean('Allow Reconciliation', help="Check this option if you want the user to reconcile entries in this account."),
2393 'shortcut': fields.char('Shortcut', size=12),
2394 'note': fields.text('Note'),
2395 'parent_id': fields.many2one('account.account.template', 'Parent Account Template', ondelete='cascade'),
2396 'child_parent_ids':fields.one2many('account.account.template', 'parent_id', 'Children'),
2397 'tax_ids': fields.many2many('account.tax.template', 'account_account_template_tax_rel', 'account_id', 'tax_id', 'Default Taxes'),
2398 'nocreate': fields.boolean('Optional create', help="If checked, the new chart of accounts will not contain this by default."),
2399 }
2400
2401 _defaults = {
2402 'reconcile': False,
2403 'type': 'view',
2404 'nocreate': False,
2405 }
2406
2407 def _check_type(self, cr, uid, ids, context=None):
2408 if context is None:
2409 context = {}
2410 accounts = self.browse(cr, uid, ids, context=context)
2411 for account in accounts:
2412 if account.parent_id and account.parent_id.type != 'view':
2413 return False
2414 return True
2415
2416 _check_recursion = check_cycle
2417 _constraints = [
2418 (_check_recursion, 'Error ! You can not create recursive account templates.', ['parent_id']),
2419 (_check_type, 'Configuration Error!\nYou can not define children to an account with internal type different of "View"! ', ['type']),
2420
2421 ]
2422
2423 def name_get(self, cr, uid, ids, context=None):
2424 if not ids:
2425 return []
2426 reads = self.read(cr, uid, ids, ['name','code'], context=context)
2427 res = []
2428 for record in reads:
2429 name = record['name']
2430 if record['code']:
2431 name = record['code']+' '+name
2432 res.append((record['id'],name ))
2433 return res
2434
2435account_account_template()
2436
2437class account_add_tmpl_wizard(osv.osv_memory):
2438 """Add one more account from the template.
2439
2440 With the 'nocreate' option, some accounts may not be created. Use this to add them later."""
2441 _name = 'account.addtmpl.wizard'
2442
2443 def _get_def_cparent(self, cr, uid, context=None):
2444 acc_obj = self.pool.get('account.account')
2445 tmpl_obj = self.pool.get('account.account.template')
2446 tids = tmpl_obj.read(cr, uid, [context['tmpl_ids']], ['parent_id'])
2447 if not tids or not tids[0]['parent_id']:
2448 return False
2449 ptids = tmpl_obj.read(cr, uid, [tids[0]['parent_id'][0]], ['code'])
2450 res = None
2451 if not ptids or not ptids[0]['code']:
2452 raise osv.except_osv(_('Error !'), _('I can not locate a parent code for the template account!'))
2453 res = acc_obj.search(cr, uid, [('code','=',ptids[0]['code'])])
2454 return res and res[0] or False
2455
2456 _columns = {
2457 'cparent_id':fields.many2one('account.account', 'Parent target', help="Creates an account with the selected template under this existing parent.", required=True),
2458 }
2459 _defaults = {
2460 'cparent_id': _get_def_cparent,
2461 }
2462
2463 def action_create(self,cr,uid,ids,context=None):
2464 if context is None:
2465 context = {}
2466 acc_obj = self.pool.get('account.account')
2467 tmpl_obj = self.pool.get('account.account.template')
2468 data = self.read(cr, uid, ids)
2469 company_id = acc_obj.read(cr, uid, [data[0]['cparent_id']], ['company_id'])[0]['company_id'][0]
2470 account_template = tmpl_obj.browse(cr, uid, context['tmpl_ids'])
2471 vals = {
2472 'name': account_template.name,
2473 'currency_id': account_template.currency_id and account_template.currency_id.id or False,
2474 'code': account_template.code,
2475 'type': account_template.type,
2476 'user_type': account_template.user_type and account_template.user_type.id or False,
2477 'reconcile': account_template.reconcile,
2478 'shortcut': account_template.shortcut,
2479 'note': account_template.note,
2480 'parent_id': data[0]['cparent_id'],
2481 'company_id': company_id,
2482 }
2483 acc_obj.create(cr, uid, vals)
2484 return {'type':'state', 'state': 'end' }
2485
2486 def action_cancel(self, cr, uid, ids, context=None):
2487 return { 'type': 'state', 'state': 'end' }
2488
2489account_add_tmpl_wizard()
2490
2491class account_tax_code_template(osv.osv):
2492
2493 _name = 'account.tax.code.template'
2494 _description = 'Tax Code Template'
2495 _order = 'code'
2496 _rec_name = 'code'
2497 _columns = {
2498 'name': fields.char('Tax Case Name', size=64, required=True),
2499 'code': fields.char('Case Code', size=64),
2500 'info': fields.text('Description'),
2501 'parent_id': fields.many2one('account.tax.code.template', 'Parent Code', select=True),
2502 'child_ids': fields.one2many('account.tax.code.template', 'parent_id', 'Child Codes'),
2503 'sign': fields.float('Sign For Parent', required=True),
2504 'notprintable':fields.boolean("Not Printable in Invoice", help="Check this box if you don't want any VAT related to this Tax Code to appear on invoices"),
2505 }
2506
2507 _defaults = {
2508 'sign': 1.0,
2509 'notprintable': False,
2510 }
2511
2512 def name_get(self, cr, uid, ids, context=None):
2513 if not ids:
2514 return []
2515 if isinstance(ids, (int, long)):
2516 ids = [ids]
2517 reads = self.read(cr, uid, ids, ['name','code'], context, load='_classic_write')
2518 return [(x['id'], (x['code'] and x['code'] + ' - ' or '') + x['name']) \
2519 for x in reads]
2520
2521 _check_recursion = check_cycle
2522 _constraints = [
2523 (_check_recursion, 'Error ! You can not create recursive Tax Codes.', ['parent_id'])
2524 ]
2525 _order = 'code,name'
2526account_tax_code_template()
2527
2528
2529class account_chart_template(osv.osv):
2530 _name="account.chart.template"
2531 _description= "Templates for Account Chart"
2532
2533 _columns={
2534 'name': fields.char('Name', size=64, required=True),
2535 'account_root_id': fields.many2one('account.account.template','Root Account',required=True,domain=[('parent_id','=',False)]),
2536 'tax_code_root_id': fields.many2one('account.tax.code.template','Root Tax Code',required=True,domain=[('parent_id','=',False)]),
2537 'tax_template_ids': fields.one2many('account.tax.template', 'chart_template_id', 'Tax Template List', help='List of all the taxes that have to be installed by the wizard'),
2538 'bank_account_view_id': fields.many2one('account.account.template','Bank Account',required=True),
2539 'property_account_receivable': fields.many2one('account.account.template','Receivable Account'),
2540 'property_account_payable': fields.many2one('account.account.template','Payable Account'),
2541 'property_account_expense_categ': fields.many2one('account.account.template','Expense Category Account'),
2542 'property_account_income_categ': fields.many2one('account.account.template','Income Category Account'),
2543 'property_account_expense': fields.many2one('account.account.template','Expense Account on Product Template'),
2544 'property_account_income': fields.many2one('account.account.template','Income Account on Product Template'),
2545 'property_reserve_and_surplus_account': fields.many2one('account.account.template', 'Reserve and Profit/Loss Account', domain=[('type', '=', 'payable')], help='This Account is used for transferring Profit/Loss(If It is Profit: Amount will be added, Loss: Amount will be deducted.), Which is calculated from Profilt & Loss Report'),
2546 'property_account_income_opening': fields.many2one('account.account.template','Opening Entries Income Account'),
2547 'property_account_expense_opening': fields.many2one('account.account.template','Opening Entries Expense Account'),
2548 }
2549
2550account_chart_template()
2551
2552class account_tax_template(osv.osv):
2553
2554 _name = 'account.tax.template'
2555 _description = 'Templates for Taxes'
2556
2557 _columns = {
2558 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
2559 'name': fields.char('Tax Name', size=64, required=True),
2560 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the taxes lines from lower sequences to higher ones. The order is important if you have a tax that has several tax children. In this case, the evaluation order is important."),
2561 'amount': fields.float('Amount', required=True, digits=(14,4), help="For Tax Type percent enter % ratio between 0-1."),
2562 'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True),
2563 'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True, help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
2564 'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
2565 'account_collected_id':fields.many2one('account.account.template', 'Invoice Tax Account'),
2566 'account_paid_id':fields.many2one('account.account.template', 'Refund Tax Account'),
2567 'parent_id':fields.many2one('account.tax.template', 'Parent Tax Account', select=True),
2568 'child_depend':fields.boolean('Tax on Children', help="Set if the tax computation is based on the computation of child taxes rather than on the total amount."),
2569 'python_compute':fields.text('Python Code'),
2570 'python_compute_inv':fields.text('Python Code (reverse)'),
2571 'python_applicable':fields.text('Python Code'),
2572
2573 #
2574 # Fields used for the VAT declaration
2575 #
2576 'base_code_id': fields.many2one('account.tax.code.template', 'Base Code', help="Use this code for the VAT declaration."),
2577 'tax_code_id': fields.many2one('account.tax.code.template', 'Tax Code', help="Use this code for the VAT declaration."),
2578 'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
2579 'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
2580
2581 # Same fields for refund invoices
2582
2583 'ref_base_code_id': fields.many2one('account.tax.code.template', 'Refund Base Code', help="Use this code for the VAT declaration."),
2584 'ref_tax_code_id': fields.many2one('account.tax.code.template', 'Refund Tax Code', help="Use this code for the VAT declaration."),
2585 'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
2586 'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
2587 'include_base_amount': fields.boolean('Include in Base Amount', help="Set if the amount of tax must be included in the base amount before computing the next taxes."),
2588 'description': fields.char('Internal Name', size=32),
2589 'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Use In', required=True,),
2590 'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
2591 }
2592
2593 def name_get(self, cr, uid, ids, context=None):
2594 if not ids:
2595 return []
2596 res = []
2597 for record in self.read(cr, uid, ids, ['description','name'], context=context):
2598 name = record['description'] and record['description'] or record['name']
2599 res.append((record['id'],name ))
2600 return res
2601
2602 def _default_company(self, cr, uid, context=None):
2603 user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
2604 if user.company_id:
2605 return user.company_id.id
2606 return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
2607
2608 _defaults = {
2609 'python_compute': lambda *a: '''# price_unit\n# address: res.partner.address object or False\n# product: product.product object or None\n# partner: res.partner object or None\n\nresult = price_unit * 0.10''',
2610 'python_compute_inv': lambda *a: '''# price_unit\n# address: res.partner.address object or False\n# product: product.product object or False\n\nresult = price_unit * 0.10''',
2611 'applicable_type': 'true',
2612 'type': 'percent',
2613 'amount': 0,
2614 'sequence': 1,
2615 'ref_tax_sign': 1,
2616 'ref_base_sign': 1,
2617 'tax_sign': 1,
2618 'base_sign': 1,
2619 'include_base_amount': False,
2620 'type_tax_use': 'all',
2621 'price_include': 0,
2622 }
2623 _order = 'sequence'
2624
2625account_tax_template()
2626
2627# Fiscal Position Templates
2628
2629class account_fiscal_position_template(osv.osv):
2630 _name = 'account.fiscal.position.template'
2631 _description = 'Template for Fiscal Position'
2632
2633 _columns = {
2634 'name': fields.char('Fiscal Position Template', size=64, required=True),
2635 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
2636 'account_ids': fields.one2many('account.fiscal.position.account.template', 'position_id', 'Account Mapping'),
2637 'tax_ids': fields.one2many('account.fiscal.position.tax.template', 'position_id', 'Tax Mapping')
2638 }
2639
2640account_fiscal_position_template()
2641
2642class account_fiscal_position_tax_template(osv.osv):
2643 _name = 'account.fiscal.position.tax.template'
2644 _description = 'Template Tax Fiscal Position'
2645 _rec_name = 'position_id'
2646
2647 _columns = {
2648 'position_id': fields.many2one('account.fiscal.position.template', 'Fiscal Position', required=True, ondelete='cascade'),
2649 'tax_src_id': fields.many2one('account.tax.template', 'Tax Source', required=True),
2650 'tax_dest_id': fields.many2one('account.tax.template', 'Replacement Tax')
2651 }
2652
2653account_fiscal_position_tax_template()
2654
2655class account_fiscal_position_account_template(osv.osv):
2656 _name = 'account.fiscal.position.account.template'
2657 _description = 'Template Account Fiscal Mapping'
2658 _rec_name = 'position_id'
2659 _columns = {
2660 'position_id': fields.many2one('account.fiscal.position.template', 'Fiscal Mapping', required=True, ondelete='cascade'),
2661 'account_src_id': fields.many2one('account.account.template', 'Account Source', domain=[('type','<>','view')], required=True),
2662 'account_dest_id': fields.many2one('account.account.template', 'Account Destination', domain=[('type','<>','view')], required=True)
2663 }
2664
2665account_fiscal_position_account_template()
2666
2667# ---------------------------------------------------------
2668# Account Financial Report
2669# ---------------------------------------------------------
2670
2671class account_financial_report(osv.osv):
2672 _name = "account.financial.report"
2673 _description = "Account Report"
2674
2675 def _get_level(self, cr, uid, ids, field_name, arg, context=None):
2676 res = {}
2677 for report in self.browse(cr, uid, ids, context=context):
2678 level = 0
2679 if report.parent_id:
2680 level = report.parent_id.level + 1
2681 res[report.id] = level
2682 return res
2683
2684 def _get_children_by_order(self, cr, uid, ids, context=None):
2685 res = []
2686 for id in ids:
2687 res.append(id)
2688 ids2 = self.search(cr, uid, [('parent_id', '=', id)], order='sequence ASC', context=context)
2689 res += self._get_children_by_order(cr, uid, ids2, context=context)
2690 return res
2691
2692 def _get_balance(self, cr, uid, ids, name, args, context=None):
2693 res = {}
2694 res_all = {}
2695 for report in self.browse(cr, uid, ids, context=context):
2696 balance = 0.0
2697 if report.id in res_all:
2698 balance = res_all[report.id]
2699 elif report.type == 'accounts':
2700 # it's the sum of balance of the linked accounts
2701 for a in report.account_ids:
2702 balance += a.balance
2703 elif report.type == 'account_report' and report.account_report_id:
2704 # it's the amount of the linked report
2705 res2 = self._get_balance(cr, uid, [report.account_report_id.id], 'balance', False, context=context)
2706 res_all.update(res2)
2707 for key, value in res2.items():
2708 balance += value
2709 elif report.type == 'sum':
2710 # it's the sum of balance of the children of this account.report
2711 #for child in report.children_ids:
2712 res2 = self._get_balance(cr, uid, [rec.id for rec in report.children_ids], 'balance', False, context=context)
2713 res_all.update(res2)
2714 for key, value in res2.items():
2715 balance += value
2716 res[report.id] = balance
2717 res_all[report.id] = balance
2718 return res
2719
2720 _columns = {
2721 'name': fields.char('Report Name', size=128, required=True),
2722 'parent_id': fields.many2one('account.financial.report', 'Parent'),
2723 'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'),
2724 'sequence': fields.integer('Sequence'),
2725 'note': fields.text('Notes'),
2726 'balance': fields.function(_get_balance, 'Balance'),
2727 'level': fields.function(_get_level, string='Level', store=True, type='integer'),
2728 'type': fields.selection([
2729 ('sum','View'),
2730 ('accounts','Accounts'),
2731 ('account_type','Account Type'),
2732 ('account_report','Report Value'),
2733 ],'Type'),
2734 'account_ids': fields.many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts'),
2735 'display_detail': fields.boolean('Display details', help='Display every account with its balance instead of the sum.'),
2736 'account_report_id': fields.many2one('account.financial.report', 'Report Value'),
2737 'account_type_ids': fields.many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types'),
2738 }
2739
2740 _defaults = {
2741 'type': 'sum',
2742 }
2743
2744account_financial_report()
2745
2746# ---------------------------------------------------------
2747# Account generation from template wizards
2748# ---------------------------------------------------------
2749
2750class wizard_multi_charts_accounts(osv.osv_memory):
2751 """
2752 Create a new account chart for a company.
2753 Wizards ask for:
2754 * a company
2755 * an account chart template
2756 * a number of digits for formatting code of non-view accounts
2757 * a list of bank accounts owned by the company
2758 Then, the wizard:
2759 * generates all accounts from the template and assigns them to the right company
2760 * generates all taxes and tax codes, changing account assignations
2761 * generates all accounting properties and assigns them correctly
2762 """
2763 _name='wizard.multi.charts.accounts'
2764 _inherit = 'res.config'
2765
2766 _columns = {
2767 'company_id':fields.many2one('res.company', 'Company', required=True),
2768 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
2769 'bank_accounts_id': fields.one2many('account.bank.accounts.wizard', 'bank_account_id', 'Cash and Banks', required=True),
2770 'code_digits':fields.integer('# of Digits', required=True, help="No. of Digits to use for account code"),
2771 'seq_journal':fields.boolean('Separated Journal Sequences', help="Check this box if you want to use a different sequence for each created journal. Otherwise, all will use the same sequence."),
2772 "sale_tax": fields.many2one("account.tax.template", "Default Sale Tax"),
2773 "purchase_tax": fields.many2one("account.tax.template", "Default Purchase Tax"),
2774 }
2775 def onchange_chart_template_id(self, cr, uid, ids, chart_template_id=False, context=None):
2776 res = {}
2777 res['value'] = {}
2778 res['value']["sale_tax"] = False
2779 res['value']["purchase_tax"] = False
2780 if chart_template_id:
2781 # default tax is given by the lowesst sequence. For same sequence we will take the latest created as it will be the case for tax created while isntalling the generic chart of account
2782 sale_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
2783 , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all'))], order="sequence, id desc")
2784 purchase_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
2785 , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all'))], order="sequence, id desc")
2786
2787 res['value']["sale_tax"] = sale_tax_ids and sale_tax_ids[0] or False
2788 res['value']["purchase_tax"] = purchase_tax_ids and purchase_tax_ids[0] or False
2789 return res
2790
2791 def _get_purchase_tax(self, cr, uid, context=None):
2792 ids = self.pool.get('account.chart.template').search(cr, uid, [], context=context)
2793 if ids:
2794 chart_template_id = ids[0]
2795 purchase_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
2796 , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all'))], order="sequence")
2797 return purchase_tax_ids and purchase_tax_ids[0] or False
2798 return False
2799
2800 def _get_sale_tax(self, cr, uid, context=None):
2801 ids = self.pool.get('account.chart.template').search(cr, uid, [], context=context)
2802 if ids:
2803 chart_template_id = ids[0]
2804 sale_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
2805 , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all'))], order="sequence")
2806 return sale_tax_ids and sale_tax_ids[0] or False
2807 return False
2808
2809 def _get_chart(self, cr, uid, context=None):
2810 ids = self.pool.get('account.chart.template').search(cr, uid, [], context=context)
2811 if ids:
2812 return ids[0]
2813 return False
2814
2815 def _get_default_accounts(self, cr, uid, context=None):
2816 return [
2817 {'acc_name': _('Cash'),'account_type':'cash'}
2818 ]
2819
2820 _defaults = {
2821 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, [uid], c)[0].company_id.id,
2822 'chart_template_id': _get_chart,
2823 'bank_accounts_id': _get_default_accounts,
2824 'sale_tax': _get_sale_tax,
2825 'purchase_tax': _get_purchase_tax,
2826 'code_digits': 6,
2827 'seq_journal': True
2828 }
2829
2830 def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
2831 res = super(wizard_multi_charts_accounts, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
2832 cmp_select = []
2833 company_ids = self.pool.get('res.company').search(cr, uid, [], context=context)
2834 #display in the widget selection of companies, only the companies that haven't been configured yet (but don't care about the demo chart of accounts)
2835 cr.execute("SELECT company_id FROM account_account WHERE active = 't' AND account_account.parent_id IS NULL AND name != %s", ("Chart For Automated Tests",))
2836 configured_cmp = [r[0] for r in cr.fetchall()]
2837 unconfigured_cmp = list(set(company_ids)-set(configured_cmp))
2838 for field in res['fields']:
2839 if field == 'company_id':
2840 res['fields'][field]['domain'] = [('id','in',unconfigured_cmp)]
2841 res['fields'][field]['selection'] = [('', '')]
2842 if unconfigured_cmp:
2843 cmp_select = [(line.id, line.name) for line in self.pool.get('res.company').browse(cr, uid, unconfigured_cmp)]
2844 res['fields'][field]['selection'] = cmp_select
2845 return res
2846
2847 def execute(self, cr, uid, ids, context=None):
2848 obj_multi = self.browse(cr, uid, ids[0])
2849 obj_acc = self.pool.get('account.account')
2850 obj_acc_tax = self.pool.get('account.tax')
2851 obj_journal = self.pool.get('account.journal')
2852 obj_acc_template = self.pool.get('account.account.template')
2853 obj_fiscal_position_template = self.pool.get('account.fiscal.position.template')
2854 obj_fiscal_position = self.pool.get('account.fiscal.position')
2855 obj_data = self.pool.get('ir.model.data')
2856 analytic_journal_obj = self.pool.get('account.analytic.journal')
2857 obj_tax_code = self.pool.get('account.tax.code')
2858 obj_tax_code_template = self.pool.get('account.tax.code.template')
2859 ir_values_obj = self.pool.get('ir.values')
2860 # Creating Account
2861 obj_acc_root = obj_multi.chart_template_id.account_root_id
2862 tax_code_root_id = obj_multi.chart_template_id.tax_code_root_id.id
2863 company_id = obj_multi.company_id.id
2864
2865 #new code
2866 acc_template_ref = {}
2867 tax_template_ref = {}
2868 tax_code_template_ref = {}
2869 todo_dict = {}
2870
2871 #create all the tax code
2872 children_tax_code_template = obj_tax_code_template.search(cr, uid, [('parent_id','child_of',[tax_code_root_id])], order='id')
2873 children_tax_code_template.sort()
2874 for tax_code_template in obj_tax_code_template.browse(cr, uid, children_tax_code_template, context=context):
2875 vals = {
2876 'name': (tax_code_root_id == tax_code_template.id) and obj_multi.company_id.name or tax_code_template.name,
2877 'code': tax_code_template.code,
2878 'info': tax_code_template.info,
2879 'parent_id': tax_code_template.parent_id and ((tax_code_template.parent_id.id in tax_code_template_ref) and tax_code_template_ref[tax_code_template.parent_id.id]) or False,
2880 'company_id': company_id,
2881 'sign': tax_code_template.sign,
2882 }
2883 new_tax_code = obj_tax_code.create(cr, uid, vals)
2884 #recording the new tax code to do the mapping
2885 tax_code_template_ref[tax_code_template.id] = new_tax_code
2886
2887 #create all the tax
2888 tax_template_to_tax = {}
2889 for tax in obj_multi.chart_template_id.tax_template_ids:
2890 #create it
2891 vals_tax = {
2892 'name':tax.name,
2893 'sequence': tax.sequence,
2894 'amount':tax.amount,
2895 'type':tax.type,
2896 'applicable_type': tax.applicable_type,
2897 'domain':tax.domain,
2898 'parent_id': tax.parent_id and ((tax.parent_id.id in tax_template_ref) and tax_template_ref[tax.parent_id.id]) or False,
2899 'child_depend': tax.child_depend,
2900 'python_compute': tax.python_compute,
2901 'python_compute_inv': tax.python_compute_inv,
2902 'python_applicable': tax.python_applicable,
2903 'base_code_id': tax.base_code_id and ((tax.base_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.base_code_id.id]) or False,
2904 'tax_code_id': tax.tax_code_id and ((tax.tax_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.tax_code_id.id]) or False,
2905 'base_sign': tax.base_sign,
2906 'tax_sign': tax.tax_sign,
2907 'ref_base_code_id': tax.ref_base_code_id and ((tax.ref_base_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.ref_base_code_id.id]) or False,
2908 'ref_tax_code_id': tax.ref_tax_code_id and ((tax.ref_tax_code_id.id in tax_code_template_ref) and tax_code_template_ref[tax.ref_tax_code_id.id]) or False,
2909 'ref_base_sign': tax.ref_base_sign,
2910 'ref_tax_sign': tax.ref_tax_sign,
2911 'include_base_amount': tax.include_base_amount,
2912 'description':tax.description,
2913 'company_id': company_id,
2914 'type_tax_use': tax.type_tax_use,
2915 'price_include': tax.price_include
2916 }
2917 new_tax = obj_acc_tax.create(cr, uid, vals_tax)
2918 tax_template_to_tax[tax.id] = new_tax
2919 #as the accounts have not been created yet, we have to wait before filling these fields
2920 todo_dict[new_tax] = {
2921 'account_collected_id': tax.account_collected_id and tax.account_collected_id.id or False,
2922 'account_paid_id': tax.account_paid_id and tax.account_paid_id.id or False,
2923 }
2924 tax_template_ref[tax.id] = new_tax
2925 #deactivate the parent_store functionnality on account_account for rapidity purpose
2926 ctx = context and context.copy() or {}
2927 ctx['defer_parent_store_computation'] = True
2928
2929 children_acc_template = obj_acc_template.search(cr, uid, [('parent_id','child_of',[obj_acc_root.id]),('nocreate','!=',True)])
2930 children_acc_template.sort()
2931 for account_template in obj_acc_template.browse(cr, uid, children_acc_template, context=context):
2932 tax_ids = []
2933 for tax in account_template.tax_ids:
2934 tax_ids.append(tax_template_ref[tax.id])
2935 #create the account_account
2936
2937 dig = obj_multi.code_digits
2938 code_main = account_template.code and len(account_template.code) or 0
2939 code_acc = account_template.code or ''
2940 if code_main>0 and code_main<=dig and account_template.type != 'view':
2941 code_acc=str(code_acc) + (str('0'*(dig-code_main)))
2942 vals={
2943 'name': (obj_acc_root.id == account_template.id) and obj_multi.company_id.name or account_template.name,
2944 'currency_id': account_template.currency_id and account_template.currency_id.id or False,
2945 'code': code_acc,
2946 'type': account_template.type,
2947 'user_type': account_template.user_type and account_template.user_type.id or False,
2948 'reconcile': account_template.reconcile,
2949 'shortcut': account_template.shortcut,
2950 'note': account_template.note,
2951 'parent_id': account_template.parent_id and ((account_template.parent_id.id in acc_template_ref) and acc_template_ref[account_template.parent_id.id]) or False,
2952 'tax_ids': [(6,0,tax_ids)],
2953 'company_id': company_id,
2954 }
2955 new_account = obj_acc.create(cr, uid, vals, context=ctx)
2956 acc_template_ref[account_template.id] = new_account
2957
2958
2959 #reactivate the parent_store functionnality on account_account
2960 obj_acc._parent_store_compute(cr)
2961
2962 for key,value in todo_dict.items():
2963 if value['account_collected_id'] or value['account_paid_id']:
2964 obj_acc_tax.write(cr, uid, [key], {
2965 'account_collected_id': acc_template_ref.get(value['account_collected_id'], False),
2966 'account_paid_id': acc_template_ref.get(value['account_paid_id'], False),
2967 })
2968
2969 # Creating Journals
2970 data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_sp_journal_view')])
2971 data = obj_data.browse(cr, uid, data_id[0], context=context)
2972 view_id = data.res_id
2973
2974 #Sales Journal
2975 analytical_sale_ids = analytic_journal_obj.search(cr,uid,[('type','=','sale')])
2976 analytical_journal_sale = analytical_sale_ids and analytical_sale_ids[0] or False
2977
2978 vals_journal = {
2979 'name': _('Sales Journal'),
2980 'type': 'sale',
2981 'code': _('SAJ'),
2982 'view_id': view_id,
2983 'company_id': company_id,
2984 'analytic_journal_id': analytical_journal_sale,
2985 }
2986
2987 if obj_multi.chart_template_id.property_account_receivable:
2988 vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
2989 vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
2990
2991 obj_journal.create(cr,uid,vals_journal)
2992
2993 # Purchase Journal
2994 analytical_purchase_ids = analytic_journal_obj.search(cr,uid,[('type','=','purchase')])
2995 analytical_journal_purchase = analytical_purchase_ids and analytical_purchase_ids[0] or False
2996
2997 vals_journal = {
2998 'name': _('Purchase Journal'),
2999 'type': 'purchase',
3000 'code': _('EXJ'),
3001 'view_id': view_id,
3002 'company_id': company_id,
3003 'analytic_journal_id': analytical_journal_purchase,
3004 }
3005
3006 if obj_multi.chart_template_id.property_account_payable:
3007 vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3008 vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3009 obj_journal.create(cr,uid,vals_journal)
3010
3011 # Creating Journals Sales Refund and Purchase Refund
3012 data_id = obj_data.search(cr, uid, [('model', '=', 'account.journal.view'), ('name', '=', 'account_sp_refund_journal_view')], context=context)
3013 data = obj_data.browse(cr, uid, data_id[0], context=context)
3014 view_id = data.res_id
3015
3016 #Sales Refund Journal
3017 vals_journal = {
3018 'name': _('Sales Refund Journal'),
3019 'type': 'sale_refund',
3020 'code': _('SCNJ'),
3021 'view_id': view_id,
3022 'analytic_journal_id': analytical_journal_sale,
3023 'company_id': company_id
3024 }
3025
3026 if obj_multi.chart_template_id.property_account_receivable:
3027 vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
3028 vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
3029
3030 obj_journal.create(cr, uid, vals_journal, context=context)
3031
3032 # Purchase Refund Journal
3033 vals_journal = {
3034 'name': _('Purchase Refund Journal'),
3035 'type': 'purchase_refund',
3036 'code': _('ECNJ'),
3037 'view_id': view_id,
3038 'analytic_journal_id': analytical_journal_purchase,
3039 'company_id': company_id
3040 }
3041
3042 if obj_multi.chart_template_id.property_account_payable:
3043 vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3044 vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3045
3046 obj_journal.create(cr, uid, vals_journal, context=context)
3047
3048 # Miscellaneous Journal
3049 data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_view')])
3050 data = obj_data.browse(cr, uid, data_id[0], context=context)
3051 view_id = data.res_id
3052
3053 analytical_miscellaneous_ids = analytic_journal_obj.search(cr, uid, [('type', '=', 'situation')], context=context)
3054 analytical_journal_miscellaneous = analytical_miscellaneous_ids and analytical_miscellaneous_ids[0] or False
3055
3056 vals_journal = {
3057 'name': _('Miscellaneous Journal'),
3058 'type': 'general',
3059 'code': _('MISC'),
3060 'view_id': view_id,
3061 'analytic_journal_id': analytical_journal_miscellaneous,
3062 'company_id': company_id
3063 }
3064
3065 obj_journal.create(cr, uid, vals_journal, context=context)
3066
3067 # Opening Entries Journal
3068 if obj_multi.chart_template_id.property_account_income_opening and obj_multi.chart_template_id.property_account_expense_opening:
3069 vals_journal = {
3070 'name': _('Opening Entries Journal'),
3071 'type': 'situation',
3072 'code': _('OPEJ'),
3073 'view_id': view_id,
3074 'company_id': company_id,
3075 'centralisation': True,
3076 'default_credit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_income_opening.id],
3077 'default_debit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_expense_opening.id]
3078 }
3079 obj_journal.create(cr, uid, vals_journal, context=context)
3080
3081 # Bank Journals
3082 data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
3083 data = obj_data.browse(cr, uid, data_id[0], context=context)
3084 view_id_cash = data.res_id
3085
3086 data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view_multi')])
3087 data = obj_data.browse(cr, uid, data_id[0], context=context)
3088 view_id_cur = data.res_id
3089 ref_acc_bank = obj_multi.chart_template_id.bank_account_view_id
3090
3091 current_num = 1
3092 valid = True
3093 for line in obj_multi.bank_accounts_id:
3094 #create the account_account for this bank journal
3095 tmp = line.acc_name
3096 dig = obj_multi.code_digits
3097 if not ref_acc_bank.code:
3098 raise osv.except_osv(_('Configuration Error !'), _('The bank account defined on the selected chart of account hasn\'t a code.'))
3099 while True:
3100 new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num)
3101 ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', company_id)])
3102 if not ids:
3103 break
3104 else:
3105 current_num += 1
3106 vals = {
3107 'name': tmp,
3108 'currency_id': line.currency_id and line.currency_id.id or False,
3109 'code': new_code,
3110 'type': 'liquidity',
3111 'user_type': account_template.user_type and account_template.user_type.id or False,
3112 'reconcile': True,
3113 'parent_id': acc_template_ref[ref_acc_bank.id] or False,
3114 'company_id': company_id,
3115 }
3116 acc_cash_id = obj_acc.create(cr,uid,vals)
3117
3118 #create the bank journal
3119 vals_journal = {
3120 'name': vals['name'],
3121 'code': _('BNK') + str(current_num),
3122 'type': line.account_type == 'cash' and 'cash' or 'bank',
3123 'company_id': company_id,
3124 'analytic_journal_id': False,
3125 'currency_id': False,
3126 }
3127 if line.currency_id:
3128 vals_journal['view_id'] = view_id_cur
3129 vals_journal['currency'] = line.currency_id.id
3130 else:
3131 vals_journal['view_id'] = view_id_cash
3132 vals_journal['default_credit_account_id'] = acc_cash_id
3133 vals_journal['default_debit_account_id'] = acc_cash_id
3134 obj_journal.create(cr, uid, vals_journal)
3135 current_num += 1
3136 valid = True
3137
3138 #create the properties
3139 property_obj = self.pool.get('ir.property')
3140 fields_obj = self.pool.get('ir.model.fields')
3141
3142 todo_list = [
3143 ('property_account_receivable','res.partner','account.account'),
3144 ('property_account_payable','res.partner','account.account'),
3145 ('property_account_expense_categ','product.category','account.account'),
3146 ('property_account_income_categ','product.category','account.account'),
3147 ('property_account_expense','product.template','account.account'),
3148 ('property_account_income','product.template','account.account'),
3149 ('property_reserve_and_surplus_account','res.company','account.account')
3150 ]
3151 for record in todo_list:
3152 r = []
3153 r = property_obj.search(cr, uid, [('name','=', record[0] ),('company_id','=',company_id)])
3154 account = getattr(obj_multi.chart_template_id, record[0])
3155 field = fields_obj.search(cr, uid, [('name','=',record[0]),('model','=',record[1]),('relation','=',record[2])])
3156 vals = {
3157 'name': record[0],
3158 'company_id': company_id,
3159 'fields_id': field[0],
3160 'value': account and 'account.account,' + str(acc_template_ref[account.id]) or False,
3161 }
3162
3163 if r:
3164 #the property exist: modify it
3165 property_obj.write(cr, uid, r, vals)
3166 else:
3167 #create the property
3168 property_obj.create(cr, uid, vals)
3169
3170 fp_ids = obj_fiscal_position_template.search(cr, uid, [('chart_template_id', '=', obj_multi.chart_template_id.id)])
3171
3172 if fp_ids:
3173 obj_tax_fp = self.pool.get('account.fiscal.position.tax')
3174 obj_ac_fp = self.pool.get('account.fiscal.position.account')
3175
3176 for position in obj_fiscal_position_template.browse(cr, uid, fp_ids, context=context):
3177
3178 vals_fp = {
3179 'company_id': company_id,
3180 'name': position.name,
3181 }
3182 new_fp = obj_fiscal_position.create(cr, uid, vals_fp)
3183
3184 for tax in position.tax_ids:
3185 vals_tax = {
3186 'tax_src_id': tax_template_ref[tax.tax_src_id.id],
3187 'tax_dest_id': tax.tax_dest_id and tax_template_ref[tax.tax_dest_id.id] or False,
3188 'position_id': new_fp,
3189 }
3190 obj_tax_fp.create(cr, uid, vals_tax)
3191
3192 for acc in position.account_ids:
3193 vals_acc = {
3194 'account_src_id': acc_template_ref[acc.account_src_id.id],
3195 'account_dest_id': acc_template_ref[acc.account_dest_id.id],
3196 'position_id': new_fp,
3197 }
3198 obj_ac_fp.create(cr, uid, vals_acc)
3199
3200 if obj_multi.sale_tax:
3201 ir_values_obj.set(cr, uid, key='default', key2=False, name="taxes_id", company=obj_multi.company_id.id,
3202 models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.sale_tax.id]])
3203 if obj_multi.purchase_tax:
3204 ir_values_obj.set(cr, uid, key='default', key2=False, name="supplier_taxes_id", company=obj_multi.company_id.id,
3205 models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.purchase_tax.id]])
3206
3207wizard_multi_charts_accounts()
3208
3209class account_bank_accounts_wizard(osv.osv_memory):
3210 _name='account.bank.accounts.wizard'
3211
3212 _columns = {
3213 'acc_name': fields.char('Account Name.', size=64, required=True),
3214 'bank_account_id': fields.many2one('wizard.multi.charts.accounts', 'Bank Account', required=True),
3215 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
3216 'account_type': fields.selection([('cash','Cash'), ('check','Check'), ('bank','Bank')], 'Account Type', size=32),
3217 }
3218
3219account_bank_accounts_wizard()
3220
3221# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
03222
=== added file 'account/account_analytic_line.py'
--- account/account_analytic_line.py 1970-01-01 00:00:00 +0000
+++ account/account_analytic_line.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,162 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import time
23
24from osv import fields
25from osv import osv
26from tools.translate import _
27
28class account_analytic_line(osv.osv):
29 _inherit = 'account.analytic.line'
30 _description = 'Analytic Line'
31 _columns = {
32 'product_uom_id': fields.many2one('product.uom', 'UoM'),
33 'product_id': fields.many2one('product.product', 'Product'),
34 'general_account_id': fields.many2one('account.account', 'General Account', required=True, ondelete='restrict'),
35 'move_id': fields.many2one('account.move.line', 'Move Line', ondelete='cascade', select=True),
36 'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal', required=True, ondelete='restrict', select=True),
37 'code': fields.char('Code', size=8),
38 'ref': fields.char('Ref.', size=64),
39 'currency_id': fields.related('move_id', 'currency_id', type='many2one', relation='res.currency', string='Account currency', store=True, help="The related account currency if not equal to the company one.", readonly=True),
40 'amount_currency': fields.related('move_id', 'amount_currency', type='float', string='Amount currency', store=True, help="The amount expressed in the related account currency if not equal to the company one.", readonly=True),
41 }
42
43 _defaults = {
44 'date': lambda *a: time.strftime('%Y-%m-%d'),
45 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', context=c),
46 }
47 _order = 'date desc'
48
49 def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
50 if context is None:
51 context = {}
52 if context.get('from_date',False):
53 args.append(['date', '>=', context['from_date']])
54 if context.get('to_date',False):
55 args.append(['date','<=', context['to_date']])
56 return super(account_analytic_line, self).search(cr, uid, args, offset, limit,
57 order, context=context, count=count)
58
59 def _check_company(self, cr, uid, ids, context=None):
60 lines = self.browse(cr, uid, ids, context=context)
61 for l in lines:
62 if l.move_id and not l.account_id.company_id.id == l.move_id.account_id.company_id.id:
63 return False
64 return True
65
66 # Compute the cost based on the price type define into company
67 # property_valuation_price_type property
68 def on_change_unit_amount(self, cr, uid, id, prod_id, quantity, company_id,
69 unit=False, journal_id=False, context=None):
70 if context==None:
71 context={}
72 if not journal_id:
73 j_ids = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=','purchase')])
74 journal_id = j_ids and j_ids[0] or False
75 if not journal_id or not prod_id:
76 return {}
77 product_obj = self.pool.get('product.product')
78 analytic_journal_obj =self.pool.get('account.analytic.journal')
79 product_price_type_obj = self.pool.get('product.price.type')
80 j_id = analytic_journal_obj.browse(cr, uid, journal_id, context=context)
81 prod = product_obj.browse(cr, uid, prod_id, context=context)
82 result = 0.0
83 if prod_id:
84 unit = prod.uom_id.id
85 if j_id.type == 'purchase':
86 unit = prod.uom_po_id.id
87 if j_id.type <> 'sale':
88 a = prod.product_tmpl_id.property_account_expense.id
89 if not a:
90 a = prod.categ_id.property_account_expense_categ.id
91 if not a:
92 raise osv.except_osv(_('Error !'),
93 _('There is no expense account defined ' \
94 'for this product: "%s" (id:%d)') % \
95 (prod.name, prod.id,))
96 else:
97 a = prod.product_tmpl_id.property_account_income.id
98 if not a:
99 a = prod.categ_id.property_account_income_categ.id
100 if not a:
101 raise osv.except_osv(_('Error !'),
102 _('There is no income account defined ' \
103 'for this product: "%s" (id:%d)') % \
104 (prod.name, prod_id,))
105
106 flag = False
107 # Compute based on pricetype
108 product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','standard_price')], context=context)
109 pricetype = product_price_type_obj.browse(cr, uid, product_price_type_ids, context=context)[0]
110 if journal_id:
111 journal = analytic_journal_obj.browse(cr, uid, journal_id, context=context)
112 if journal.type == 'sale':
113 product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','list_price')], context)
114 if product_price_type_ids:
115 pricetype = product_price_type_obj.browse(cr, uid, product_price_type_ids, context=context)[0]
116 # Take the company currency as the reference one
117 if pricetype.field == 'list_price':
118 flag = True
119 ctx = context.copy()
120 if unit:
121 # price_get() will respect a 'uom' in its context, in order
122 # to return a default price for those units
123 ctx['uom'] = unit
124 amount_unit = prod.price_get(pricetype.field, context=ctx)[prod.id]
125 prec = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
126 amount = amount_unit * quantity or 1.0
127 result = round(amount, prec)
128 if not flag:
129 result *= -1
130 return {'value': {
131 'amount': result,
132 'general_account_id': a,
133 'product_uom_id': unit
134 }
135 }
136
137 def view_header_get(self, cr, user, view_id, view_type, context=None):
138 if context is None:
139 context = {}
140 if context.get('account_id', False):
141 # account_id in context may also be pointing to an account.account.id
142 cr.execute('select name from account_analytic_account where id=%s', (context['account_id'],))
143 res = cr.fetchone()
144 if res:
145 res = _('Entries: ')+ (res[0] or '')
146 return res
147 return False
148
149account_analytic_line()
150
151class res_partner(osv.osv):
152 """ Inherits partner and adds contract information in the partner form """
153 _inherit = 'res.partner'
154
155 _columns = {
156 'contract_ids': fields.one2many('account.analytic.account', \
157 'partner_id', 'Contracts', readonly=True),
158 }
159
160res_partner()
161
162# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0163
=== added file 'account/account_assert_test.xml'
--- account/account_assert_test.xml 1970-01-01 00:00:00 +0000
+++ account/account_assert_test.xml 2011-10-06 16:09:39 +0000
@@ -0,0 +1,8 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <assert model="account.move" search="[]" string="For all Journal Items, the state is valid implies that the sum of credits equals the sum of debits">
5 <test expr="not len(line_id) or line_id[0].state != 'valid' or (sum([l.debit - l.credit for l in line_id]) &lt;= 0.00001)"/>
6 </assert>
7 </data>
8</openerp>
09
=== added file 'account/account_bank.py'
--- account/account_bank.py 1970-01-01 00:00:00 +0000
+++ account/account_bank.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,103 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from tools.translate import _
23from osv import fields, osv
24
25class bank(osv.osv):
26 _inherit = "res.partner.bank"
27 _columns = {
28 'journal_id': fields.many2one('account.journal', 'Account Journal', help="This journal will be created automatically for this bank account when you save the record"),
29 }
30 def create(self, cr, uid, data, context={}):
31 result = super(bank, self).create(cr, uid, data, context=context)
32 self.post_write(cr, uid, [result], context=context)
33 return result
34
35 def write(self, cr, uid, ids, data, context={}):
36 result = super(bank, self).write(cr, uid, ids, data, context=context)
37 self.post_write(cr, uid, ids, context=context)
38 return result
39
40 def post_write(self, cr, uid, ids, context={}):
41 obj_acc = self.pool.get('account.account')
42 obj_data = self.pool.get('ir.model.data')
43 for bank in self.browse(cr, uid, ids, context):
44 if bank.company_id and not bank.journal_id:
45 # Find the code and parent of the bank account to create
46 dig = 6
47 current_num = 1
48 ids = obj_acc.search(cr, uid, [('type','=','liquidity')], context=context)
49 # No liquidity account exists, no template available
50 if not ids: continue
51
52 ref_acc_bank_temp = obj_acc.browse(cr, uid, ids[0], context=context)
53 ref_acc_bank = ref_acc_bank_temp.parent_id
54 while True:
55 new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num)
56 ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', bank.company_id.id)])
57 if not ids:
58 break
59 current_num += 1
60
61 acc = {
62 'name': (bank.bank_name or '')+' '+bank.acc_number,
63 'currency_id': bank.company_id.currency_id.id,
64 'code': new_code,
65 'type': 'liquidity',
66 'user_type': ref_acc_bank_temp.user_type.id,
67 'reconcile': False,
68 'parent_id': ref_acc_bank.id,
69 'company_id': bank.company_id.id,
70 }
71 acc_bank_id = obj_acc.create(cr,uid,acc,context=context)
72
73 # Get the journal view id
74 data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
75 data = obj_data.browse(cr, uid, data_id[0], context=context)
76 view_id_cash = data.res_id
77
78 jour_obj = self.pool.get('account.journal')
79 new_code = 1
80 while True:
81 code = _('BNK')+str(new_code)
82 ids = jour_obj.search(cr, uid, [('code','=',code)], context=context)
83 if not ids:
84 break
85 new_code += 1
86
87 #create the bank journal
88 vals_journal = {
89 'name': (bank.bank_name or '')+' '+bank.acc_number,
90 'code': code,
91 'type': 'bank',
92 'company_id': bank.company_id.id,
93 'analytic_journal_id': False,
94 'currency_id': False,
95 'default_credit_account_id': acc_bank_id,
96 'default_debit_account_id': acc_bank_id,
97 'view_id': view_id_cash
98 }
99 journal_id = jour_obj.create(cr, uid, vals_journal, context=context)
100
101 self.write(cr, uid, [bank.id], {'journal_id': journal_id}, context=context)
102 return True
103
0104
=== added file 'account/account_bank_statement.py'
--- account/account_bank_statement.py 1970-01-01 00:00:00 +0000
+++ account/account_bank_statement.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,484 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import time
23
24from osv import fields, osv
25from tools.translate import _
26import decimal_precision as dp
27
28class account_bank_statement(osv.osv):
29
30 def create(self, cr, uid, vals, context=None):
31 seq = 0
32 if 'line_ids' in vals:
33 for line in vals['line_ids']:
34 seq += 1
35 line[2]['sequence'] = seq
36 vals[seq - 1] = line
37 return super(account_bank_statement, self).create(cr, uid, vals, context=context)
38
39 def write(self, cr, uid, ids, vals, context=None):
40 res = super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
41 account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
42 for statement in self.browse(cr, uid, ids, context):
43 seq = 0
44 for line in statement.line_ids:
45 seq += 1
46 account_bank_statement_line_obj.write(cr, uid, [line.id], {'sequence': seq}, context=context)
47 return res
48
49 def _default_journal_id(self, cr, uid, context=None):
50 if context is None:
51 context = {}
52 journal_pool = self.pool.get('account.journal')
53 journal_type = context.get('journal_type', False)
54 journal_id = False
55 if journal_type:
56 ids = journal_pool.search(cr, uid, [('type', '=', journal_type)])
57 if ids:
58 journal_id = ids[0]
59 return journal_id
60
61 def _end_balance(self, cursor, user, ids, name, attr, context=None):
62 res_currency_obj = self.pool.get('res.currency')
63 res_users_obj = self.pool.get('res.users')
64 res = {}
65
66 company_currency_id = res_users_obj.browse(cursor, user, user,
67 context=context).company_id.currency_id.id
68
69 statements = self.browse(cursor, user, ids, context=context)
70 for statement in statements:
71 res[statement.id] = statement.balance_start
72 currency_id = statement.currency.id
73 for line in statement.move_line_ids:
74 if line.debit > 0:
75 if line.account_id.id == \
76 statement.journal_id.default_debit_account_id.id:
77 res[statement.id] += res_currency_obj.compute(cursor,
78 user, company_currency_id, currency_id,
79 line.debit, context=context)
80 else:
81 if line.account_id.id == \
82 statement.journal_id.default_credit_account_id.id:
83 res[statement.id] -= res_currency_obj.compute(cursor,
84 user, company_currency_id, currency_id,
85 line.credit, context=context)
86
87 if statement.state in ('draft', 'open'):
88 for line in statement.line_ids:
89 res[statement.id] += line.amount
90 for r in res:
91 res[r] = round(res[r], 2)
92 return res
93
94 def _get_period(self, cr, uid, context=None):
95 periods = self.pool.get('account.period').find(cr, uid)
96 if periods:
97 return periods[0]
98 return False
99
100 def _currency(self, cursor, user, ids, name, args, context=None):
101 res = {}
102 res_currency_obj = self.pool.get('res.currency')
103 res_users_obj = self.pool.get('res.users')
104 default_currency = res_users_obj.browse(cursor, user,
105 user, context=context).company_id.currency_id
106 for statement in self.browse(cursor, user, ids, context=context):
107 currency = statement.journal_id.currency
108 if not currency:
109 currency = default_currency
110 res[statement.id] = currency.id
111 currency_names = {}
112 for currency_id, currency_name in res_currency_obj.name_get(cursor,
113 user, [x for x in res.values()], context=context):
114 currency_names[currency_id] = currency_name
115 for statement_id in res.keys():
116 currency_id = res[statement_id]
117 res[statement_id] = (currency_id, currency_names[currency_id])
118 return res
119
120 def _get_statement(self, cr, uid, ids, context=None):
121 result = {}
122 for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
123 result[line.statement_id.id] = True
124 return result.keys()
125
126 _order = "date desc, id desc"
127 _name = "account.bank.statement"
128 _description = "Bank Statement"
129 _columns = {
130 'name': fields.char('Name', size=64, required=True, states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement
131 'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}),
132 'journal_id': fields.many2one('account.journal', 'Journal', required=True,
133 readonly=True, states={'draft':[('readonly',False)]}),
134 'period_id': fields.many2one('account.period', 'Period', required=True,
135 states={'confirm':[('readonly', True)]}),
136 'balance_start': fields.float('Starting Balance', digits_compute=dp.get_precision('Account'),
137 states={'confirm':[('readonly',True)]}),
138 'balance_end_real': fields.float('Ending Balance', digits_compute=dp.get_precision('Account'),
139 states={'confirm': [('readonly', True)]}),
140 'balance_end': fields.function(_end_balance,
141 store = {
142 'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
143 'account.bank.statement.line': (_get_statement, ['amount'], 10),
144 },
145 string="Computed Balance", help='Balance as calculated based on Starting Balance and transaction lines'),
146 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
147 'line_ids': fields.one2many('account.bank.statement.line',
148 'statement_id', 'Statement lines',
149 states={'confirm':[('readonly', True)]}),
150 'move_line_ids': fields.one2many('account.move.line', 'statement_id',
151 'Entry lines', states={'confirm':[('readonly',True)]}),
152 'state': fields.selection([('draft', 'New'),
153 ('open','Open'), # used by cash statements
154 ('confirm', 'Closed')],
155 'State', required=True, readonly="1",
156 help='When new statement is created the state will be \'Draft\'.\n'
157 'And after getting confirmation from the bank it will be in \'Confirmed\' state.'),
158 'currency': fields.function(_currency, string='Currency',
159 type='many2one', relation='res.currency'),
160 'account_id': fields.related('journal_id', 'default_debit_account_id', type='many2one', relation='account.account', string='Account used in this journal', readonly=True, help='used in statement reconciliation domain, but shouldn\'t be used elswhere.'),
161 }
162
163 _defaults = {
164 'name': "/",
165 'date': lambda *a: time.strftime('%Y-%m-%d'),
166 'state': 'draft',
167 'journal_id': _default_journal_id,
168 'period_id': _get_period,
169 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.bank.statement',context=c),
170 }
171
172 def onchange_date(self, cr, user, ids, date, context=None):
173 """
174 Returns a dict that contains new values and context
175 @param cr: A database cursor
176 @param user: ID of the user currently logged in
177 @param date: latest value from user input for field date
178 @param args: other arguments
179 @param context: context arguments, like lang, time zone
180 @return: Returns a dict which contains new values, and context
181 """
182 res = {}
183 period_pool = self.pool.get('account.period')
184
185 if context is None:
186 context = {}
187
188 pids = period_pool.search(cr, user, [('date_start','<=',date), ('date_stop','>=',date)])
189 if pids:
190 res.update({
191 'period_id':pids[0]
192 })
193 context.update({
194 'period_id':pids[0]
195 })
196
197 return {
198 'value':res,
199 'context':context,
200 }
201
202 def button_dummy(self, cr, uid, ids, context=None):
203 return self.write(cr, uid, ids, {}, context=context)
204
205 def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id, st_line_number, context=None):
206 if context is None:
207 context = {}
208 res_currency_obj = self.pool.get('res.currency')
209 account_move_obj = self.pool.get('account.move')
210 account_move_line_obj = self.pool.get('account.move.line')
211 account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
212 st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id, context=context)
213 st = st_line.statement_id
214
215 context.update({'date': st_line.date})
216
217 move_id = account_move_obj.create(cr, uid, {
218 'journal_id': st.journal_id.id,
219 'period_id': st.period_id.id,
220 'date': st_line.date,
221 'name': st_line_number,
222 }, context=context)
223 account_bank_statement_line_obj.write(cr, uid, [st_line.id], {
224 'move_ids': [(4, move_id, False)]
225 })
226
227 torec = []
228 if st_line.amount >= 0:
229 account_id = st.journal_id.default_credit_account_id.id
230 else:
231 account_id = st.journal_id.default_debit_account_id.id
232
233 acc_cur = ((st_line.amount<=0) and st.journal_id.default_debit_account_id) or st_line.account_id
234 context.update({
235 'res.currency.compute.account': acc_cur,
236 })
237 amount = res_currency_obj.compute(cr, uid, st.currency.id,
238 company_currency_id, st_line.amount, context=context)
239
240 val = {
241 'name': st_line.name,
242 'date': st_line.date,
243 'ref': st_line.ref,
244 'move_id': move_id,
245 'partner_id': ((st_line.partner_id) and st_line.partner_id.id) or False,
246 'account_id': (st_line.account_id) and st_line.account_id.id,
247 'credit': ((amount>0) and amount) or 0.0,
248 'debit': ((amount<0) and -amount) or 0.0,
249 'statement_id': st.id,
250 'journal_id': st.journal_id.id,
251 'period_id': st.period_id.id,
252 'currency_id': st.currency.id,
253 'analytic_account_id': st_line.analytic_account_id and st_line.analytic_account_id.id or False
254 }
255
256 if st.currency.id <> company_currency_id:
257 amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
258 st.currency.id, amount, context=context)
259 val['amount_currency'] = -amount_cur
260
261 if st_line.account_id and st_line.account_id.currency_id and st_line.account_id.currency_id.id <> company_currency_id:
262 val['currency_id'] = st_line.account_id.currency_id.id
263 amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
264 st_line.account_id.currency_id.id, amount, context=context)
265 val['amount_currency'] = -amount_cur
266
267 move_line_id = account_move_line_obj.create(cr, uid, val, context=context)
268 torec.append(move_line_id)
269
270 # Fill the secondary amount/currency
271 # if currency is not the same than the company
272 amount_currency = False
273 currency_id = False
274 if st.currency.id <> company_currency_id:
275 amount_currency = st_line.amount
276 currency_id = st.currency.id
277 account_move_line_obj.create(cr, uid, {
278 'name': st_line.name,
279 'date': st_line.date,
280 'ref': st_line.ref,
281 'move_id': move_id,
282 'partner_id': ((st_line.partner_id) and st_line.partner_id.id) or False,
283 'account_id': account_id,
284 'credit': ((amount < 0) and -amount) or 0.0,
285 'debit': ((amount > 0) and amount) or 0.0,
286 'statement_id': st.id,
287 'journal_id': st.journal_id.id,
288 'period_id': st.period_id.id,
289 'amount_currency': amount_currency,
290 'currency_id': currency_id,
291 }, context=context)
292
293 for line in account_move_line_obj.browse(cr, uid, [x.id for x in
294 account_move_obj.browse(cr, uid, move_id,
295 context=context).line_id],
296 context=context):
297 if line.state <> 'valid':
298 raise osv.except_osv(_('Error !'),
299 _('Journal Item "%s" is not valid') % line.name)
300
301 # Bank statements will not consider boolean on journal entry_posted
302 account_move_obj.post(cr, uid, [move_id], context=context)
303 return move_id
304
305 def get_next_st_line_number(self, cr, uid, st_number, st_line, context=None):
306 return st_number + '/' + str(st_line.sequence)
307
308 def balance_check(self, cr, uid, st_id, journal_type='bank', context=None):
309 st = self.browse(cr, uid, st_id, context=context)
310 if not (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001):
311 raise osv.except_osv(_('Error !'),
312 _('The statement balance is incorrect !\nThe expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
313 return True
314
315 def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
316 return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
317
318 def check_status_condition(self, cr, uid, state, journal_type='bank'):
319 return state in ('draft','open')
320
321 def button_confirm_bank(self, cr, uid, ids, context=None):
322 obj_seq = self.pool.get('ir.sequence')
323 if context is None:
324 context = {}
325
326 for st in self.browse(cr, uid, ids, context=context):
327 j_type = st.journal_id.type
328 company_currency_id = st.journal_id.company_id.currency_id.id
329 if not self.check_status_condition(cr, uid, st.state, journal_type=j_type):
330 continue
331
332 self.balance_check(cr, uid, st.id, journal_type=j_type, context=context)
333 if (not st.journal_id.default_credit_account_id) \
334 or (not st.journal_id.default_debit_account_id):
335 raise osv.except_osv(_('Configuration Error !'),
336 _('Please verify that an account is defined in the journal.'))
337
338 if not st.name == '/':
339 st_number = st.name
340 else:
341 if st.journal_id.sequence_id:
342 c = {'fiscalyear_id': st.period_id.fiscalyear_id.id}
343 st_number = obj_seq.next_by_id(cr, uid, st.journal_id.sequence_id.id, context=c)
344 else:
345 st_number = obj_seq.next_by_code(cr, uid, 'account.bank.statement')
346
347 for line in st.move_line_ids:
348 if line.state <> 'valid':
349 raise osv.except_osv(_('Error !'),
350 _('The account entries lines are not in valid state.'))
351 for st_line in st.line_ids:
352 if st_line.analytic_account_id:
353 if not st.journal_id.analytic_journal_id:
354 raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (st.journal_id.name,))
355 if not st_line.amount:
356 continue
357 st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context)
358 self.create_move_from_st_line(cr, uid, st_line.id, company_currency_id, st_line_number, context)
359
360 self.write(cr, uid, [st.id], {'name': st_number}, context=context)
361 self.log(cr, uid, st.id, _('Statement %s is confirmed, journal items are created.') % (st_number,))
362 return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
363
364 def button_cancel(self, cr, uid, ids, context=None):
365 done = []
366 account_move_obj = self.pool.get('account.move')
367 for st in self.browse(cr, uid, ids, context=context):
368 if st.state=='draft':
369 continue
370 ids = []
371 for line in st.line_ids:
372 ids += [x.id for x in line.move_ids]
373 account_move_obj.unlink(cr, uid, ids, context)
374 done.append(st.id)
375 return self.write(cr, uid, done, {'state':'draft'}, context=context)
376
377 def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
378 cr.execute('SELECT balance_end_real \
379 FROM account_bank_statement \
380 WHERE journal_id = %s AND NOT state = %s \
381 ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft'))
382 res = cr.fetchone()
383 balance_start = res and res[0] or 0.0
384 account_id = self.pool.get('account.journal').read(cr, uid, journal_id, ['default_debit_account_id'], context=context)['default_debit_account_id']
385 return {'value': {'balance_start': balance_start, 'account_id': account_id}}
386
387 def unlink(self, cr, uid, ids, context=None):
388 stat = self.read(cr, uid, ids, ['state'], context=context)
389 unlink_ids = []
390 for t in stat:
391 if t['state'] in ('draft'):
392 unlink_ids.append(t['id'])
393 else:
394 raise osv.except_osv(_('Invalid action !'), _('In order to delete a bank statement, you must first cancel it to delete related journal items.'))
395 osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
396 return True
397
398 def copy(self, cr, uid, id, default=None, context=None):
399 if default is None:
400 default = {}
401 if context is None:
402 context = {}
403 default = default.copy()
404 default['move_line_ids'] = []
405 return super(account_bank_statement, self).copy(cr, uid, id, default, context=context)
406
407account_bank_statement()
408
409class account_bank_statement_line(osv.osv):
410
411 def onchange_partner_id(self, cr, uid, ids, partner_id, context=None):
412 obj_partner = self.pool.get('res.partner')
413 if context is None:
414 context = {}
415 if not partner_id:
416 return {}
417 part = obj_partner.browse(cr, uid, partner_id, context=context)
418 if not part.supplier and not part.customer:
419 type = 'general'
420 elif part.supplier and part.customer:
421 type = 'general'
422 else:
423 if part.supplier == True:
424 type = 'supplier'
425 if part.customer == True:
426 type = 'customer'
427 res_type = self.onchange_type(cr, uid, ids, partner_id=partner_id, type=type, context=context)
428 if res_type['value'] and res_type['value'].get('account_id', False):
429 return {'value': {'type': type, 'account_id': res_type['value']['account_id']}}
430 return {'value': {'type': type}}
431
432 def onchange_type(self, cr, uid, line_id, partner_id, type, context=None):
433 res = {'value': {}}
434 obj_partner = self.pool.get('res.partner')
435 if context is None:
436 context = {}
437 if not partner_id:
438 return res
439 account_id = False
440 line = self.browse(cr, uid, line_id, context=context)
441 if not line or (line and not line[0].account_id):
442 part = obj_partner.browse(cr, uid, partner_id, context=context)
443 if type == 'supplier':
444 account_id = part.property_account_payable.id
445 else:
446 account_id = part.property_account_receivable.id
447 res['value']['account_id'] = account_id
448 return res
449
450 _order = "statement_id desc, sequence"
451 _name = "account.bank.statement.line"
452 _description = "Bank Statement Line"
453 _columns = {
454 'name': fields.char('Communication', size=64, required=True),
455 'date': fields.date('Date', required=True),
456 'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
457 'type': fields.selection([
458 ('supplier','Supplier'),
459 ('customer','Customer'),
460 ('general','General')
461 ], 'Type', required=True),
462 'partner_id': fields.many2one('res.partner', 'Partner'),
463 'account_id': fields.many2one('account.account','Account',
464 required=True),
465 'statement_id': fields.many2one('account.bank.statement', 'Statement',
466 select=True, required=True, ondelete='cascade'),
467 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'),
468 'move_ids': fields.many2many('account.move',
469 'account_bank_statement_line_move_rel', 'statement_line_id','move_id',
470 'Moves'),
471 'ref': fields.char('Reference', size=32),
472 'note': fields.text('Notes'),
473 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bank statement lines."),
474 'company_id': fields.related('statement_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
475 }
476 _defaults = {
477 'name': lambda self,cr,uid,context={}: self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement.line'),
478 'date': lambda self,cr,uid,context={}: context.get('date', time.strftime('%Y-%m-%d')),
479 'type': 'general',
480 }
481
482account_bank_statement_line()
483
484# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0485
=== added file 'account/account_bank_view.xml'
--- account/account_bank_view.xml 1970-01-01 00:00:00 +0000
+++ account/account_bank_view.xml 2011-10-06 16:09:39 +0000
@@ -0,0 +1,48 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3<data>
4
5 <!--
6 Bank Accounts
7 -->
8
9 <record id="view_partner_bank_form_inherit" model="ir.ui.view">
10 <field name="name">Partner Bank Accounts - Journal</field>
11 <field name="model">res.partner.bank</field>
12 <field name="type">form</field>
13 <field name="inherit_id" ref="base.view_partner_bank_form"/>
14 <field name="arch" type="xml">
15 <group name="bank" position="after">
16 <group name="accounting" col="2" colspan="2" attrs="{'invisible': [('company_id','=', False)]}" groups="base.group_extended">
17 <separator string="Accounting Information" colspan="2"/>
18 <field name="journal_id"/>
19 </group>
20 </group>
21 </field>
22 </record>
23
24
25 <record id="action_bank_tree" model="ir.actions.act_window">
26 <field name="name">Setup your Bank Accounts</field>
27 <field name="res_model">res.partner.bank</field>
28 <field name="view_type">form</field>
29 <field name="view_mode">tree,form</field>
30 <field name="context" eval="{'default_partner_id':ref('base.main_partner'), 'company_hide':False, 'default_company_id':ref('base.main_company'), 'search_default_my_bank':1}"/>
31 <field name="help">Configure your company's bank account and select those that must appear on the report footer. You can reorder banks in the list view. If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data.</field>
32 </record>
33 <menuitem
34 sequence="0"
35 parent="account.account_account_menu"
36 id="menu_action_bank_tree"
37 action="action_bank_tree"/>
38
39
40 <record id="account_configuration_bank_todo" model="ir.actions.todo">
41 <field name="action_id" ref="action_bank_tree"/>
42 <field name="category_id" ref="category_accounting_configuration"/>
43 <field name="sequence">4</field>
44 </record>
45
46
47</data>
48</openerp>
049
=== added file 'account/account_cash_statement.py'
--- account/account_cash_statement.py 1970-01-01 00:00:00 +0000
+++ account/account_cash_statement.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,345 @@
1# encoding: utf-8
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2008 PC Solutions (<http://pcsol.be>). All Rights Reserved
6# $Id$
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22
23import time
24
25from osv import osv, fields
26from tools.translate import _
27import decimal_precision as dp
28
29class account_cashbox_line(osv.osv):
30
31 """ Cash Box Details """
32
33 _name = 'account.cashbox.line'
34 _description = 'CashBox Line'
35 _rec_name = 'number'
36
37 def _sub_total(self, cr, uid, ids, name, arg, context=None):
38
39 """ Calculates Sub total
40 @param name: Names of fields.
41 @param arg: User defined arguments
42 @return: Dictionary of values.
43 """
44 res = {}
45 for obj in self.browse(cr, uid, ids, context=context):
46 res[obj.id] = obj.pieces * obj.number
47 return res
48
49 def on_change_sub(self, cr, uid, ids, pieces, number, *a):
50
51 """ Calculates Sub total on change of number
52 @param pieces: Names of fields.
53 @param number:
54 """
55 sub = pieces * number
56 return {'value': {'subtotal': sub or 0.0}}
57
58 _columns = {
59 'pieces': fields.float('Values', digits_compute=dp.get_precision('Account')),
60 'number': fields.integer('Number'),
61 'subtotal': fields.function(_sub_total, string='Sub Total', type='float', digits_compute=dp.get_precision('Account')),
62 'starting_id': fields.many2one('account.bank.statement', ondelete='cascade'),
63 'ending_id': fields.many2one('account.bank.statement', ondelete='cascade'),
64 }
65
66account_cashbox_line()
67
68class account_cash_statement(osv.osv):
69
70 _inherit = 'account.bank.statement'
71
72 def _get_starting_balance(self, cr, uid, ids, context=None):
73
74 """ Find starting balance
75 @param name: Names of fields.
76 @param arg: User defined arguments
77 @return: Dictionary of values.
78 """
79 res = {}
80 for statement in self.browse(cr, uid, ids, context=context):
81 amount_total = 0.0
82
83 if statement.journal_id.type not in('cash'):
84 continue
85
86 for line in statement.starting_details_ids:
87 amount_total+= line.pieces * line.number
88 res[statement.id] = {
89 'balance_start': amount_total
90 }
91 return res
92
93 def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
94 """ Find ending balance "
95 @param name: Names of fields.
96 @param arg: User defined arguments
97 @return: Dictionary of values.
98 """
99 res = {}
100 for statement in self.browse(cr, uid, ids, context=context):
101 amount_total = 0.0
102 for line in statement.ending_details_ids:
103 amount_total += line.pieces * line.number
104 res[statement.id] = amount_total
105 return res
106
107 def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
108
109 """ Find encoding total of statements "
110 @param name: Names of fields.
111 @param arg: User defined arguments
112 @return: Dictionary of values.
113 """
114 res2 = {}
115 for statement in self.browse(cr, uid, ids, context=context):
116 encoding_total=0.0
117 for line in statement.line_ids:
118 encoding_total += line.amount
119 res2[statement.id] = encoding_total
120 return res2
121
122 def _get_company(self, cr, uid, context=None):
123 user_pool = self.pool.get('res.users')
124 company_pool = self.pool.get('res.company')
125 user = user_pool.browse(cr, uid, uid, context=context)
126 company_id = user.company_id
127 if not company_id:
128 company_id = company_pool.search(cr, uid, [])
129 return company_id and company_id[0] or False
130
131 def _get_cash_open_box_lines(self, cr, uid, context=None):
132 res = []
133 curr = [1, 2, 5, 10, 20, 50, 100, 500]
134 for rs in curr:
135 dct = {
136 'pieces': rs,
137 'number': 0
138 }
139 res.append(dct)
140 journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')], context=context)
141 if journal_ids:
142 results = self.search(cr, uid, [('journal_id', 'in', journal_ids),('state', '=', 'confirm')], context=context)
143 if results:
144 cash_st = self.browse(cr, uid, results, context=context)[0]
145 for cash_line in cash_st.ending_details_ids:
146 for r in res:
147 if cash_line.pieces == r['pieces']:
148 r['number'] = cash_line.number
149 return res
150
151 def _get_default_cash_close_box_lines(self, cr, uid, context=None):
152 res = []
153 curr = [1, 2, 5, 10, 20, 50, 100, 500]
154 for rs in curr:
155 dct = {
156 'pieces': rs,
157 'number': 0
158 }
159 res.append(dct)
160 return res
161
162 def _get_cash_close_box_lines(self, cr, uid, context=None):
163 res = []
164 curr = [1, 2, 5, 10, 20, 50, 100, 500]
165 for rs in curr:
166 dct = {
167 'pieces': rs,
168 'number': 0
169 }
170 res.append((0, 0, dct))
171 return res
172
173 def _get_cash_open_close_box_lines(self, cr, uid, context=None):
174 res = {}
175 start_l = []
176 end_l = []
177 starting_details = self._get_cash_open_box_lines(cr, uid, context=context)
178 ending_details = self._get_default_cash_close_box_lines(cr, uid, context)
179 for start in starting_details:
180 start_l.append((0, 0, start))
181 for end in ending_details:
182 end_l.append((0, 0, end))
183 res['start'] = start_l
184 res['end'] = end_l
185 return res
186
187 def _get_statement(self, cr, uid, ids, context=None):
188 result = {}
189 for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
190 result[line.statement_id.id] = True
191 return result.keys()
192
193 _columns = {
194 'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Cash Transaction", help="Total cash transactions",
195 store = {
196 'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
197 'account.bank.statement.line': (_get_statement, ['amount'], 10),
198 }),
199 'closing_date': fields.datetime("Closed On"),
200 'balance_end_cash': fields.function(_balance_end_cash, store=True, string='Closing Balance', help="Closing balance based on cashBox"),
201 'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'),
202 'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'),
203 'user_id': fields.many2one('res.users', 'Responsible', required=False),
204 }
205 _defaults = {
206 'state': 'draft',
207 'date': lambda self,cr,uid,context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")),
208 'user_id': lambda self, cr, uid, context=None: uid,
209 'starting_details_ids': _get_cash_open_box_lines,
210 'ending_details_ids': _get_default_cash_close_box_lines
211 }
212
213 def create(self, cr, uid, vals, context=None):
214 if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash':
215 open_close = self._get_cash_open_close_box_lines(cr, uid, context)
216 if vals.get('starting_details_ids', False):
217 for start in vals.get('starting_details_ids'):
218 dict_val = start[2]
219 for end in open_close['end']:
220 if end[2]['pieces'] == dict_val['pieces']:
221 end[2]['number'] += dict_val['number']
222 vals.update({
223# 'ending_details_ids': open_close['start'],
224 'starting_details_ids': open_close['end']
225 })
226 else:
227 vals.update({
228 'ending_details_ids': False,
229 'starting_details_ids': False
230 })
231 res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
232 self.write(cr, uid, [res_id], {})
233 return res_id
234
235 def write(self, cr, uid, ids, vals, context=None):
236 """
237 Update redord(s) comes in {ids}, with new value comes as {vals}
238 return True on success, False otherwise
239
240 @param cr: cursor to database
241 @param user: id of current user
242 @param ids: list of record ids to be update
243 @param vals: dict of new values to be set
244 @param context: context arguments, like lang, time zone
245
246 @return: True on success, False otherwise
247 """
248
249 super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
250 res = self._get_starting_balance(cr, uid, ids)
251 for rs in res:
252 super(account_cash_statement, self).write(cr, uid, [rs], res.get(rs))
253 return True
254
255 def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
256 """ Changes balance start and starting details if journal_id changes"
257 @param statement_id: Changed statement_id
258 @param journal_id: Changed journal_id
259 @return: Dictionary of changed values
260 """
261 res = {}
262 balance_start = 0.0
263 if not journal_id:
264 res.update({
265 'balance_start': balance_start
266 })
267 return res
268 return super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
269
270 def _equal_balance(self, cr, uid, cash_id, context=None):
271 statement = self.browse(cr, uid, cash_id, context=context)
272 self.write(cr, uid, [cash_id], {'balance_end_real': statement.balance_end})
273 statement.balance_end_real = statement.balance_end
274 if statement.balance_end != statement.balance_end_cash:
275 return False
276 return True
277
278 def _user_allow(self, cr, uid, statement_id, context=None):
279 return True
280
281 def button_open(self, cr, uid, ids, context=None):
282 """ Changes statement state to Running.
283 @return: True
284 """
285 obj_seq = self.pool.get('ir.sequence')
286 if context is None:
287 context = {}
288 statement_pool = self.pool.get('account.bank.statement')
289 for statement in statement_pool.browse(cr, uid, ids, context=context):
290 vals = {}
291 if not self._user_allow(cr, uid, statement.id, context=context):
292 raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name)))
293
294 if statement.name and statement.name == '/':
295 if statement.journal_id.sequence_id:
296 c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
297 st_number = obj_seq.next_by_id(cr, uid, statement.journal_id.sequence_id.id, context=c)
298 else:
299 st_number = obj_seq.next_by_code(cr, uid, 'account.cash.statement')
300 vals.update({
301 'name': st_number
302 })
303
304 vals.update({
305 'state': 'open',
306 })
307 self.write(cr, uid, [statement.id], vals, context=context)
308 return True
309
310 def balance_check(self, cr, uid, cash_id, journal_type='bank', context=None):
311 if journal_type == 'bank':
312 return super(account_cash_statement, self).balance_check(cr, uid, cash_id, journal_type, context)
313 if not self._equal_balance(cr, uid, cash_id, context):
314 raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance !'))
315 return True
316
317 def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
318 if journal_type == 'bank':
319 return super(account_cash_statement, self).statement_close(cr, uid, ids, journal_type, context)
320 vals = {
321 'state':'confirm',
322 'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")
323 }
324 return self.write(cr, uid, ids, vals, context=context)
325
326 def check_status_condition(self, cr, uid, state, journal_type='bank'):
327 if journal_type == 'bank':
328 return super(account_cash_statement, self).check_status_condition(cr, uid, state, journal_type)
329 return state=='open'
330
331 def button_confirm_cash(self, cr, uid, ids, context=None):
332 super(account_cash_statement, self).button_confirm_bank(cr, uid, ids, context=context)
333 return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context)
334
335 def button_cancel(self, cr, uid, ids, context=None):
336 cash_box_line_pool = self.pool.get('account.cashbox.line')
337 super(account_cash_statement, self).button_cancel(cr, uid, ids, context=context)
338 for st in self.browse(cr, uid, ids, context):
339 for end in st.ending_details_ids:
340 cash_box_line_pool.write(cr, uid, [end.id], {'number': 0})
341 return True
342
343account_cash_statement()
344
345# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0346
=== added file 'account/account_end_fy.xml'
--- account/account_end_fy.xml 1970-01-01 00:00:00 +0000
+++ account/account_end_fy.xml 2011-10-06 16:09:39 +0000
@@ -0,0 +1,20 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="action_account_period_tree" model="ir.actions.act_window">
6 <field name="name">Close a Period</field>
7 <field name="res_model">account.period</field>
8 <field name="view_type">form</field>
9 <field name="view_id" ref="view_account_period_tree"/>
10 <field name="context">{'search_default_draft': 1}</field>
11 <field name="help">A period is a fiscal period of time during which accounting entries should be recorded for accounting related activities. Monthly period is the norm but depending on your countries or company needs, you could also have quarterly periods. Closing a period will make it impossible to record new accounting entries, all new entries should then be made on the following open period. Close a period when you do not want to record new entries and want to lock this period for tax related calculation.</field>
12 </record>
13 <menuitem
14 action="action_account_period_tree"
15 id="menu_action_account_period_close_tree"
16 parent="account.menu_account_end_year_treatments"
17 sequence="0" groups="base.group_extended"/>
18
19 </data>
20</openerp>
021
=== added file 'account/account_installer.xml'
--- account/account_installer.xml 1970-01-01 00:00:00 +0000
+++ account/account_installer.xml 2011-10-06 16:09:39 +0000
@@ -0,0 +1,112 @@
1<openerp>
2 <data>
3 <record id="view_account_configuration_installer" model="ir.ui.view">
4 <field name="name">account.installer.form</field>
5 <field name="model">account.installer</field>
6 <field name="type">form</field>
7 <field name="inherit_id" ref="base.res_config_installer"/>
8 <field name="arch" type="xml">
9 <data>
10 <form position="attributes">
11 <attribute name="string">Accounting Application Configuration</attribute>
12 </form>
13 <separator string="title" position="attributes">
14 <attribute name="string">Configure Your Chart of Accounts</attribute>
15 </separator>
16 <xpath expr="//label[@string='description']" position="attributes">
17 <attribute name="string">The default Chart of Accounts is matching your country selection. If no certified Chart of Accounts exists for your specified country, a generic one can be installed and will be selected by default.</attribute>
18 </xpath>
19 <xpath expr="//button[@string='Install Modules']" position="attributes">
20 <attribute name="string">Configure</attribute>
21 </xpath>
22 <xpath expr="//separator[@string=&quot;vsep&quot;]" position="attributes">
23 <attribute name="rowspan">23</attribute>
24 <attribute name="string"/>
25 </xpath>
26 <group colspan="8" position="inside">
27 <group colspan="4" width="600">
28 <field name="charts"/>
29 <group colspan="4" groups="account.group_account_user">
30 <separator col="4" colspan="4" string="Configure Fiscal Year"/>
31 <field name="company_id" colspan="4" widget="selection"/><!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
32 <field name="date_start" on_change="on_change_start_date(date_start)"/>
33 <field name="date_stop"/>
34 <field name="period" colspan="4"/>
35 </group>
36 <group colspan="4" attrs="{'invisible':[('charts','!=','configurable')]}">
37 <field name="sale_tax" on_change="on_change_tax(sale_tax)" attrs="{'required':[('charts','=','configurable')]}"/>
38 <field name="purchase_tax" groups="base.group_extended"/>
39 </group>
40 </group>
41 </group>
42 </data>
43 </field>
44 </record>
45
46 <record id="action_account_configuration_installer" model="ir.actions.act_window">
47 <field name="name">Install your Chart of Accounts</field>
48 <field name="type">ir.actions.act_window</field>
49 <field name="res_model">account.installer</field>
50 <field name="view_id" ref="view_account_configuration_installer"/>
51 <field name="view_type">form</field>
52 <field name="view_mode">form</field>
53 <field name="target">new</field>
54 </record>
55
56 <record id="category_accounting_configuration" model="ir.actions.todo.category">
57 <field name="name">Accounting</field>
58 <field name="sequence">5</field>
59 </record>
60
61 <record id="account_configuration_installer_todo" model="ir.actions.todo">
62 <field name="action_id" ref="action_account_configuration_installer"/>
63 <field name="category_id" ref="category_accounting_configuration"/>
64 <field name="sequence">3</field>
65 <field name="type">automatic</field>
66 </record>
67
68 <record id="action_view_financial_accounts_installer" model="ir.actions.act_window">
69 <field name="name">Review your Financial Accounts</field>
70 <field name="type">ir.actions.act_window</field>
71 <field name="res_model">account.account</field>
72 <field name="view_type">form</field>
73 <field name="view_mode">tree,form</field>
74 <field name="context">{'config_invisible': False}</field>
75 </record>
76
77 <record id="view_financial_accounts_todo" model="ir.actions.todo">
78 <field name="action_id" ref="action_view_financial_accounts_installer" />
79 <field name="category_id" ref="category_accounting_configuration" />
80 <field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
81 </record>
82
83 <record id="action_review_financial_journals_installer" model="ir.actions.act_window">
84 <field name="name">Review your Financial Journals</field>
85 <field name="type">ir.actions.act_window</field>
86 <field name="res_model">account.journal</field>
87 <field name="view_type">form</field>
88 <field name="view_mode">tree,form</field>
89 <field name="help">Setup your accounting journals. For bank accounts, it's better to use the 'Setup Your Bank Accounts' tool that will automatically create the accounts and journals for you.</field>
90 </record>
91
92 <record id="review_financial_journals_todo" model="ir.actions.todo">
93 <field name="action_id" ref="action_review_financial_journals_installer" />
94 <field name="category_id" ref="category_accounting_configuration" />
95 <field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
96 </record>
97 <record id="action_review_payment_terms_installer" model="ir.actions.act_window">
98 <field name="name">Review your Payment Terms</field>
99 <field name="type">ir.actions.act_window</field>
100 <field name="res_model">account.payment.term</field>
101 <field name="view_type">form</field>
102 <field name="view_mode">tree,form</field>
103 <field name="help">Payment terms define the conditions to pay a customer or supplier invoice in one or several payments. Customers periodic reminders will use the payment terms for each letter. Each customer or supplier can be assigned to one of these payment terms.</field>
104 </record>
105
106 <record id="review_payment_terms_todo" model="ir.actions.todo">
107 <field name="action_id" ref="action_review_payment_terms_installer" />
108 <field name="category_id" ref="category_accounting_configuration" />
109 <field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
110 </record>
111 </data>
112</openerp>
0113
=== added file 'account/account_invoice.py'
--- account/account_invoice.py 1970-01-01 00:00:00 +0000
+++ account/account_invoice.py 2011-10-06 16:09:39 +0000
@@ -0,0 +1,1641 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import time
23from lxml import etree
24import decimal_precision as dp
25
26import netsvc
27import pooler
28from osv import fields, osv, orm
29from tools.translate import _
30
31class account_invoice(osv.osv):
32 def _amount_all(self, cr, uid, ids, name, args, context=None):
33 res = {}
34 for invoice in self.browse(cr, uid, ids, context=context):
35 res[invoice.id] = {
36 'amount_untaxed': 0.0,
37 'amount_tax': 0.0,
38 'amount_total': 0.0
39 }
40 for line in invoice.invoice_line:
41 res[invoice.id]['amount_untaxed'] += line.price_subtotal
42 for line in invoice.tax_line:
43 res[invoice.id]['amount_tax'] += line.amount
44 res[invoice.id]['amount_total'] = res[invoice.id]['amount_tax'] + res[invoice.id]['amount_untaxed']
45 return res
46
47 def _get_journal(self, cr, uid, context=None):
48 if context is None:
49 context = {}
50 type_inv = context.get('type', 'out_invoice')
51 user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
52 company_id = context.get('company_id', user.company_id.id)
53 type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale_refund', 'in_refund': 'purchase_refund'}
54 journal_obj = self.pool.get('account.journal')
55 res = journal_obj.search(cr, uid, [('type', '=', type2journal.get(type_inv, 'sale')),
56 ('company_id', '=', company_id)],
57 limit=1)
58 return res and res[0] or False
59
60 def _get_currency(self, cr, uid, context=None):
61 user = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, [uid], context=context)[0]
62 if user.company_id:
63 return user.company_id.currency_id.id
64 return pooler.get_pool(cr.dbname).get('res.currency').search(cr, uid, [('rate','=', 1.0)])[0]
65
66 def _get_journal_analytic(self, cr, uid, type_inv, context=None):
67 type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale', 'in_refund': 'purchase'}
68 tt = type2journal.get(type_inv, 'sale')
69 result = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=',tt)], context=context)
70 if not result:
71 raise osv.except_osv(_('No Analytic Journal !'),_("You must define an analytic journal of type '%s' !") % (tt,))
72 return result[0]
73
74 def _get_type(self, cr, uid, context=None):
75 if context is None:
76 context = {}
77 return context.get('type', 'out_invoice')
78
79 def _reconciled(self, cr, uid, ids, name, args, context=None):
80 res = {}
81 for id in ids:
82 res[id] = self.test_paid(cr, uid, [id])
83 return res
84
85 def _get_reference_type(self, cr, uid, context=None):
86 return [('none', _('Free Reference'))]
87
88 def _amount_residual(self, cr, uid, ids, name, args, context=None):
89 result = {}
90 for invoice in self.browse(cr, uid, ids, context=context):
91 result[invoice.id] = 0.0
92 if invoice.move_id:
93 for m in invoice.move_id.line_id:
94 if m.account_id.type in ('receivable','payable'):
95 result[invoice.id] += m.amount_residual_currency
96 return result
97
98 # Give Journal Items related to the payment reconciled to this invoice
99 # Return ids of partial and total payments related to the selected invoices
100 def _get_lines(self, cr, uid, ids, name, arg, context=None):
101 res = {}
102 for invoice in self.browse(cr, uid, ids, context=context):
103 id = invoice.id
104 res[id] = []
105 if not invoice.move_id:
106 continue
107 data_lines = [x for x in invoice.move_id.line_id if x.account_id.id == invoice.account_id.id]
108 partial_ids = []
109 for line in data_lines:
110 ids_line = []
111 if line.reconcile_id:
112 ids_line = line.reconcile_id.line_id
113 elif line.reconcile_partial_id:
114 ids_line = line.reconcile_partial_id.line_partial_ids
115 l = map(lambda x: x.id, ids_line)
116 partial_ids.append(line.id)
117 res[id] =[x for x in l if x <> line.id and x not in partial_ids]
118 return res
119
120 def _get_invoice_line(self, cr, uid, ids, context=None):
121 result = {}
122 for line in self.pool.get('account.invoice.line').browse(cr, uid, ids, context=context):
123 result[line.invoice_id.id] = True
124 return result.keys()
125
126 def _get_invoice_tax(self, cr, uid, ids, context=None):
127 result = {}
128 for tax in self.pool.get('account.invoice.tax').browse(cr, uid, ids, context=context):
129 result[tax.invoice_id.id] = True
130 return result.keys()
131
132 def _compute_lines(self, cr, uid, ids, name, args, context=None):
133 result = {}
134 for invoice in self.browse(cr, uid, ids, context=context):
135 src = []
136 lines = []
137 if invoice.move_id:
138 for m in invoice.move_id.line_id:
139 temp_lines = []
140 if m.reconcile_id:
141 temp_lines = map(lambda x: x.id, m.reconcile_id.line_id)
142 elif m.reconcile_partial_id:
143 temp_lines = map(lambda x: x.id, m.reconcile_partial_id.line_partial_ids)
144 lines += [x for x in temp_lines if x not in lines]
145 src.append(m.id)
146
147 lines = filter(lambda x: x not in src, lines)
148 result[invoice.id] = lines
149 return result
150
151 def _get_invoice_from_line(self, cr, uid, ids, context=None):
152 move = {}
153 for line in self.pool.get('account.move.line').browse(cr, uid, ids, context=context):
154 if line.reconcile_partial_id:
155 for line2 in line.reconcile_partial_id.line_partial_ids:
156 move[line2.move_id.id] = True
157 if line.reconcile_id:
158 for line2 in line.reconcile_id.line_id:
159 move[line2.move_id.id] = True
160 invoice_ids = []
161 if move:
162 invoice_ids = self.pool.get('account.invoice').search(cr, uid, [('move_id','in',move.keys())], context=context)
163 return invoice_ids
164
165 def _get_invoice_from_reconcile(self, cr, uid, ids, context=None):
166 move = {}
167 for r in self.pool.get('account.move.reconcile').browse(cr, uid, ids, context=context):
168 for line in r.line_partial_ids:
169 move[line.move_id.id] = True
170 for line in r.line_id:
171 move[line.move_id.id] = True
172
173 invoice_ids = []
174 if move:
175 invoice_ids = self.pool.get('account.invoice').search(cr, uid, [('move_id','in',move.keys())], context=context)
176 return invoice_ids
177
178 _name = "account.invoice"
179 _description = 'Invoice'
180 _order = "id desc"
181
182 _columns = {
183 'name': fields.char('Description', size=64, select=True, readonly=True, states={'draft':[('readonly',False)]}),
184 'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}),
185 'type': fields.selection([
186 ('out_invoice','Customer Invoice'),
187 ('in_invoice','Supplier Invoice'),
188 ('out_refund','Customer Refund'),
189 ('in_refund','Supplier Refund'),
190 ],'Type', readonly=True, select=True, change_default=True),
191
192 'number': fields.related('move_id','name', type='char', readonly=True, size=64, relation='account.move', store=True, string='Number'),
193 'internal_number': fields.char('Invoice Number', size=32, readonly=True, help="Unique number of the invoice, computed automatically when the invoice is created."),
194 'reference': fields.char('Invoice Reference', size=64, help="The partner reference of this invoice."),
195 'reference_type': fields.selection(_get_reference_type, 'Reference Type',
196 required=True, readonly=True, states={'draft':[('readonly',False)]}),
197 'comment': fields.text('Additional Information'),
198
199 'state': fields.selection([
200 ('draft','Draft'),
201 ('proforma','Pro-forma'),
202 ('proforma2','Pro-forma'),
203 ('open','Open'),
204 ('paid','Paid'),
205 ('cancel','Cancelled')
206 ],'State', select=True, readonly=True,
207 help=' * The \'Draft\' state is used when a user is encoding a new and unconfirmed Invoice. \
208 \n* The \'Pro-forma\' when invoice is in Pro-forma state,invoice does not have an invoice number. \
209 \n* The \'Open\' state is used when user create invoice,a invoice number is generated.Its in open state till user does not pay invoice. \
210 \n* The \'Paid\' state is set automatically when invoice is paid.\
211 \n* The \'Cancelled\' state is used when user cancel invoice.'),
212 'date_invoice': fields.date('Invoice Date', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]}, select=True, help="Keep empty to use the current date"),
213 'date_due': fields.date('Due Date', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]}, select=True,
214 help="If you use payment terms, the due date will be computed automatically at the generation "\
215 "of accounting entries. If you keep the payment term and the due date empty, it means direct payment. The payment term may compute several due dates, for example 50% now, 50% in one month."),
216 'partner_id': fields.many2one('res.partner', 'Partner', change_default=True, readonly=True, required=True, states={'draft':[('readonly',False)]}),
217 'address_contact_id': fields.many2one('res.partner.address', 'Contact Address', readonly=True, states={'draft':[('readonly',False)]}),
218 'address_invoice_id': fields.many2one('res.partner.address', 'Invoice Address', readonly=True, required=True, states={'draft':[('readonly',False)]}),
219 'payment_term': fields.many2one('account.payment.term', 'Payment Term',readonly=True, states={'draft':[('readonly',False)]},
220 help="If you use payment terms, the due date will be computed automatically at the generation "\
221 "of accounting entries. If you keep the payment term and the due date empty, it means direct payment. "\
222 "The payment term may compute several due dates, for example 50% now, 50% in one month."),
223 'period_id': fields.many2one('account.period', 'Force Period', domain=[('state','<>','done')], help="Keep empty to use the period of the validation(invoice) date.", readonly=True, states={'draft':[('readonly',False)]}),
224
225 'account_id': fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="The partner account used for this invoice."),
226 'invoice_line': fields.one2many('account.invoice.line', 'invoice_id', 'Invoice Lines', readonly=True, states={'draft':[('readonly',False)]}),
227 'tax_line': fields.one2many('account.invoice.tax', 'invoice_id', 'Tax Lines', readonly=True, states={'draft':[('readonly',False)]}),
228
229 'move_id': fields.many2one('account.move', 'Journal Entry', readonly=True, select=1, ondelete='restrict', help="Link to the automatically generated Journal Items."),
230 'amount_untaxed': fields.function(_amount_all, digits_compute=dp.get_precision('Account'), string='Untaxed',
231 store={
232 'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20),
233 'account.invoice.tax': (_get_invoice_tax, None, 20),
234 'account.invoice.line': (_get_invoice_line, ['price_unit','invoice_line_tax_id','quantity','discount','invoice_id'], 20),
235 },
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches