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
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2011-10-06 16:09:39 +0000
4@@ -0,0 +1,1 @@
5+.*
6
7=== renamed file '.bzrignore' => '.bzrignore.moved'
8=== added directory 'account'
9=== added file 'account/__init__.py'
10--- account/__init__.py 1970-01-01 00:00:00 +0000
11+++ account/__init__.py 2011-10-06 16:09:39 +0000
12@@ -0,0 +1,39 @@
13+# -*- coding: utf-8 -*-
14+##############################################################################
15+#
16+# OpenERP, Open Source Management Solution
17+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
18+#
19+# This program is free software: you can redistribute it and/or modify
20+# it under the terms of the GNU Affero General Public License as
21+# published by the Free Software Foundation, either version 3 of the
22+# License, or (at your option) any later version.
23+#
24+# This program is distributed in the hope that it will be useful,
25+# but WITHOUT ANY WARRANTY; without even the implied warranty of
26+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27+# GNU Affero General Public License for more details.
28+#
29+# You should have received a copy of the GNU Affero General Public License
30+# along with this program. If not, see <http://www.gnu.org/licenses/>.
31+#
32+##############################################################################
33+
34+import account
35+import installer
36+import project
37+import partner
38+import account_invoice
39+import account_bank_statement
40+import account_bank
41+import account_cash_statement
42+import account_move_line
43+import account_analytic_line
44+import wizard
45+import report
46+import product
47+import ir_sequence
48+import company
49+import res_currency
50+
51+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
52
53=== added file 'account/__openerp__.py'
54--- account/__openerp__.py 1970-01-01 00:00:00 +0000
55+++ account/__openerp__.py 2011-10-06 16:09:39 +0000
56@@ -0,0 +1,156 @@
57+# -*- coding: utf-8 -*-
58+##############################################################################
59+#
60+# OpenERP, Open Source Management Solution
61+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
62+#
63+# This program is free software: you can redistribute it and/or modify
64+# it under the terms of the GNU Affero General Public License as
65+# published by the Free Software Foundation, either version 3 of the
66+# License, or (at your option) any later version.
67+#
68+# This program is distributed in the hope that it will be useful,
69+# but WITHOUT ANY WARRANTY; without even the implied warranty of
70+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
71+# GNU Affero General Public License for more details.
72+#
73+# You should have received a copy of the GNU Affero General Public License
74+# along with this program. If not, see <http://www.gnu.org/licenses/>.
75+#
76+##############################################################################
77+{
78+ "name" : "Accounting and Financial Management",
79+ "version" : "1.1",
80+ "author" : "OpenERP SA",
81+ "category": 'Accounting & Finance',
82+ 'complexity': "normal",
83+ "description": """
84+Accounting and Financial Management.
85+====================================
86+
87+Financial and accounting module that covers:
88+--------------------------------------------
89+General accountings
90+Cost / Analytic accounting
91+Third party accounting
92+Taxes management
93+Budgets
94+Customer and Supplier Invoices
95+Bank statements
96+Reconciliation process by partner
97+
98+Creates a dashboard for accountants that includes:
99+--------------------------------------------------
100+* List of Customer Invoice to Approve
101+* Company Analysis
102+* Graph of Aged Receivables
103+* Graph of Treasury
104+
105+The processes like maintaining of general ledger is done through the defined financial Journals (entry move line or
106+grouping is maintained through journal) for a particular financial year and for preparation of vouchers there is a
107+module named account_voucher.
108+ """,
109+ 'website': 'http://www.openerp.com',
110+ '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'],
111+ 'init_xml': [],
112+ "depends" : ["base_setup", "product", "analytic", "process","board"],
113+ 'update_xml': [
114+ 'security/account_security.xml',
115+ 'security/ir.model.access.csv',
116+ 'account_menuitem.xml',
117+ 'report/account_invoice_report_view.xml',
118+ 'report/account_entries_report_view.xml',
119+ 'report/account_treasury_report_view.xml',
120+ 'report/account_report_view.xml',
121+ 'report/account_analytic_entries_report_view.xml',
122+ 'wizard/account_move_bank_reconcile_view.xml',
123+ 'wizard/account_use_model_view.xml',
124+ 'account_installer.xml',
125+ 'wizard/account_period_close_view.xml',
126+ 'account_view.xml',
127+ 'account_report.xml',
128+ 'wizard/account_report_common_view.xml',
129+ 'wizard/account_invoice_refund_view.xml',
130+ 'wizard/account_fiscalyear_close_state.xml',
131+ 'wizard/account_chart_view.xml',
132+ 'wizard/account_tax_chart_view.xml',
133+ 'wizard/account_move_journal_view.xml',
134+ 'wizard/account_move_line_reconcile_select_view.xml',
135+ 'wizard/account_open_closed_fiscalyear_view.xml',
136+ 'wizard/account_move_line_unreconcile_select_view.xml',
137+ 'wizard/account_vat_view.xml',
138+ 'wizard/account_report_print_journal_view.xml',
139+ 'wizard/account_report_general_journal_view.xml',
140+ 'wizard/account_report_central_journal_view.xml',
141+ 'wizard/account_subscription_generate_view.xml',
142+ 'wizard/account_fiscalyear_close_view.xml',
143+ 'wizard/account_state_open_view.xml',
144+ 'wizard/account_journal_select_view.xml',
145+ 'wizard/account_change_currency_view.xml',
146+ 'wizard/account_validate_move_view.xml',
147+ 'wizard/account_unreconcile_view.xml',
148+ 'wizard/account_report_general_ledger_view.xml',
149+ 'wizard/account_invoice_state_view.xml',
150+ 'wizard/account_report_partner_balance_view.xml',
151+ 'wizard/account_report_account_balance_view.xml',
152+ 'wizard/account_report_aged_partner_balance_view.xml',
153+ 'wizard/account_report_partner_ledger_view.xml',
154+ 'wizard/account_reconcile_view.xml',
155+ 'wizard/account_reconcile_partner_process_view.xml',
156+ 'wizard/account_automatic_reconcile_view.xml',
157+ 'wizard/account_financial_report_view.xml',
158+ 'project/wizard/project_account_analytic_line_view.xml',
159+ 'account_end_fy.xml',
160+ 'account_invoice_view.xml',
161+ 'partner_view.xml',
162+ 'data/account_data.xml',
163+ 'account_invoice_workflow.xml',
164+ 'project/project_view.xml',
165+ 'project/project_report.xml',
166+ 'project/wizard/account_analytic_balance_report_view.xml',
167+ 'project/wizard/account_analytic_cost_ledger_view.xml',
168+ 'project/wizard/account_analytic_inverted_balance_report.xml',
169+ 'project/wizard/account_analytic_journal_report_view.xml',
170+ 'project/wizard/account_analytic_cost_ledger_for_journal_report_view.xml',
171+ 'project/wizard/account_analytic_chart_view.xml',
172+ 'product_view.xml',
173+ 'account_assert_test.xml',
174+ 'process/statement_process.xml',
175+ 'process/customer_invoice_process.xml',
176+ 'process/supplier_invoice_process.xml',
177+ 'ir_sequence_view.xml',
178+ 'company_view.xml',
179+ 'board_account_view.xml',
180+ "wizard/account_report_profit_loss_view.xml",
181+ "wizard/account_report_balance_sheet_view.xml",
182+ "account_bank_view.xml"
183+ ],
184+ 'demo_xml': [
185+ 'demo/account_demo.xml',
186+ 'project/project_demo.xml',
187+ 'project/analytic_account_demo.xml',
188+ 'demo/account_minimal.xml',
189+ 'demo/account_invoice_demo.xml',
190+# 'account_unit_test.xml',
191+ ],
192+ 'test': [
193+ 'test/account_customer_invoice.yml',
194+ 'test/account_supplier_invoice.yml',
195+ 'test/account_change_currency.yml',
196+ 'test/chart_of_account.yml',
197+ 'test/account_period_close.yml',
198+ 'test/account_fiscalyear_close_state.yml',
199+ 'test/account_use_model.yml',
200+ 'test/account_validate_account_move.yml',
201+ 'test/account_fiscalyear_close.yml',
202+ 'test/account_bank_statement.yml',
203+ 'test/account_cash_statement.yml',
204+ 'test/account_report.yml',
205+
206+
207+ ],
208+ 'installable': True,
209+ 'active': False,
210+ 'certificate': '0080331923549',
211+}
212+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
213
214=== added file 'account/account.py'
215--- account/account.py 1970-01-01 00:00:00 +0000
216+++ account/account.py 2011-10-06 16:09:39 +0000
217@@ -0,0 +1,3221 @@
218+# -*- coding: utf-8 -*-
219+##############################################################################
220+#
221+# OpenERP, Open Source Management Solution
222+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
223+#
224+# This program is free software: you can redistribute it and/or modify
225+# it under the terms of the GNU Affero General Public License as
226+# published by the Free Software Foundation, either version 3 of the
227+# License, or (at your option) any later version.
228+#
229+# This program is distributed in the hope that it will be useful,
230+# but WITHOUT ANY WARRANTY; without even the implied warranty of
231+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
232+# GNU Affero General Public License for more details.
233+#
234+# You should have received a copy of the GNU Affero General Public License
235+# along with this program. If not, see <http://www.gnu.org/licenses/>.
236+#
237+##############################################################################
238+
239+import time
240+from datetime import datetime
241+from dateutil.relativedelta import relativedelta
242+from operator import itemgetter
243+
244+import netsvc
245+import pooler
246+from osv import fields, osv
247+import decimal_precision as dp
248+from tools.translate import _
249+
250+def check_cycle(self, cr, uid, ids, context=None):
251+ """ climbs the ``self._table.parent_id`` chains for 100 levels or
252+ until it can't find any more parent(s)
253+
254+ Returns true if it runs out of parents (no cycle), false if
255+ it can recurse 100 times without ending all chains
256+ """
257+ level = 100
258+ while len(ids):
259+ cr.execute('SELECT DISTINCT parent_id '\
260+ 'FROM '+self._table+' '\
261+ 'WHERE id IN %s '\
262+ 'AND parent_id IS NOT NULL',(tuple(ids),))
263+ ids = map(itemgetter(0), cr.fetchall())
264+ if not level:
265+ return False
266+ level -= 1
267+ return True
268+
269+class account_payment_term(osv.osv):
270+ _name = "account.payment.term"
271+ _description = "Payment Term"
272+ _columns = {
273+ 'name': fields.char('Payment Term', size=64, translate=True, required=True),
274+ '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."),
275+ 'note': fields.text('Description', translate=True),
276+ 'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'),
277+ }
278+ _defaults = {
279+ 'active': 1,
280+ }
281+ _order = "name"
282+
283+ def compute(self, cr, uid, id, value, date_ref=False, context=None):
284+ if not date_ref:
285+ date_ref = datetime.now().strftime('%Y-%m-%d')
286+ pt = self.browse(cr, uid, id, context=context)
287+ amount = value
288+ result = []
289+ obj_precision = self.pool.get('decimal.precision')
290+ for line in pt.line_ids:
291+ prec = obj_precision.precision_get(cr, uid, 'Account')
292+ if line.value == 'fixed':
293+ amt = round(line.value_amount, prec)
294+ elif line.value == 'procent':
295+ amt = round(value * line.value_amount, prec)
296+ elif line.value == 'balance':
297+ amt = round(amount, prec)
298+ if amt:
299+ next_date = (datetime.strptime(date_ref, '%Y-%m-%d') + relativedelta(days=line.days))
300+ if line.days2 < 0:
301+ next_first_date = next_date + relativedelta(day=1,months=1) #Getting 1st of next month
302+ next_date = next_first_date + relativedelta(days=line.days2)
303+ if line.days2 > 0:
304+ next_date += relativedelta(day=line.days2, months=1)
305+ result.append( (next_date.strftime('%Y-%m-%d'), amt) )
306+ amount -= amt
307+ return result
308+
309+account_payment_term()
310+
311+class account_payment_term_line(osv.osv):
312+ _name = "account.payment.term.line"
313+ _description = "Payment Term Line"
314+ _columns = {
315+ 'name': fields.char('Line Name', size=32, required=True),
316+ '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"),
317+ 'value': fields.selection([('procent', 'Percent'),
318+ ('balance', 'Balance'),
319+ ('fixed', 'Fixed Amount')], 'Valuation',
320+ 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."""),
321+
322+ 'value_amount': fields.float('Amount To Pay', digits_compute=dp.get_precision('Payment Term'), help="For percent enter a ratio between 0-1."),
323+ 'days': fields.integer('Number of Days', required=True, help="Number of days to add before computation of the day of month." \
324+ "If Date=15/01, Number of Days=22, Day of Month=-1, then the due date is 28/02."),
325+ '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)."),
326+ 'payment_id': fields.many2one('account.payment.term', 'Payment Term', required=True, select=True),
327+ }
328+ _defaults = {
329+ 'value': 'balance',
330+ 'sequence': 5,
331+ 'days2': 0,
332+ }
333+ _order = "sequence"
334+
335+ def _check_percent(self, cr, uid, ids, context=None):
336+ obj = self.browse(cr, uid, ids[0], context=context)
337+ if obj.value == 'procent' and ( obj.value_amount < 0.0 or obj.value_amount > 1.0):
338+ return False
339+ return True
340+
341+ _constraints = [
342+ (_check_percent, 'Percentages for Payment Term Line must be between 0 and 1, Example: 0.02 for 2% ', ['value_amount']),
343+ ]
344+
345+account_payment_term_line()
346+
347+class account_account_type(osv.osv):
348+ _name = "account.account.type"
349+ _description = "Account Type"
350+ _columns = {
351+ 'name': fields.char('Account Type', size=64, required=True),
352+ 'code': fields.char('Code', size=32, required=True),
353+ '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.
354+
355+ 'None' means that nothing will be done.
356+ 'Balance' will generally be used for cash accounts.
357+ 'Detail' will copy each existing journal item of the previous year, even the reconciled ones.
358+ 'Unreconciled' will copy only the journal items that were unreconciled on the first day of the new fiscal year."""),
359+ '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.'),
360+ 'report_type':fields.selection([
361+ ('none','/'),
362+ ('income','Profit & Loss (Income Accounts)'),
363+ ('expense','Profit & Loss (Expense Accounts)'),
364+ ('asset','Balance Sheet (Assets Accounts)'),
365+ ('liability','Balance Sheet (Liability Accounts)')
366+ ],'P&L / BS Category', select=True, readonly=False, help="This field is used to generate legal reports: profit and loss, balance sheet.", required=True),
367+ 'note': fields.text('Description'),
368+ }
369+ _defaults = {
370+ 'close_method': 'none',
371+ 'sign': 1,
372+ 'report_type': 'none',
373+ }
374+ _order = "code"
375+
376+account_account_type()
377+
378+def _code_get(self, cr, uid, context=None):
379+ acc_type_obj = self.pool.get('account.account.type')
380+ ids = acc_type_obj.search(cr, uid, [])
381+ res = acc_type_obj.read(cr, uid, ids, ['code', 'name'], context=context)
382+ return [(r['code'], r['name']) for r in res]
383+
384+#----------------------------------------------------------
385+# Accounts
386+#----------------------------------------------------------
387+
388+class account_tax(osv.osv):
389+ _name = 'account.tax'
390+account_tax()
391+
392+class account_account(osv.osv):
393+ _order = "parent_left"
394+ _parent_order = "code"
395+ _name = "account.account"
396+ _description = "Account"
397+ _parent_store = True
398+ logger = netsvc.Logger()
399+
400+ def search(self, cr, uid, args, offset=0, limit=None, order=None,
401+ context=None, count=False):
402+ if context is None:
403+ context = {}
404+ pos = 0
405+
406+ while pos < len(args):
407+
408+ if args[pos][0] == 'code' and args[pos][1] in ('like', 'ilike') and args[pos][2]:
409+ args[pos] = ('code', '=like', str(args[pos][2].replace('%', ''))+'%')
410+ if args[pos][0] == 'journal_id':
411+ if not args[pos][2]:
412+ del args[pos]
413+ continue
414+ jour = self.pool.get('account.journal').browse(cr, uid, args[pos][2], context=context)
415+ if (not (jour.account_control_ids or jour.type_control_ids)) or not args[pos][2]:
416+ args[pos] = ('type','not in',('consolidation','view'))
417+ continue
418+ ids3 = map(lambda x: x.id, jour.type_control_ids)
419+ ids1 = super(account_account, self).search(cr, uid, [('user_type', 'in', ids3)])
420+ ids1 += map(lambda x: x.id, jour.account_control_ids)
421+ args[pos] = ('id', 'in', ids1)
422+ pos += 1
423+
424+ if context and context.has_key('consolidate_children'): #add consolidated children of accounts
425+ ids = super(account_account, self).search(cr, uid, args, offset, limit,
426+ order, context=context, count=count)
427+ for consolidate_child in self.browse(cr, uid, context['account_id'], context=context).child_consol_ids:
428+ ids.append(consolidate_child.id)
429+ return ids
430+
431+ return super(account_account, self).search(cr, uid, args, offset, limit,
432+ order, context=context, count=count)
433+
434+ def _get_children_and_consol(self, cr, uid, ids, context=None):
435+ #this function search for all the children and all consolidated children (recursively) of the given account ids
436+ ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context)
437+ ids3 = []
438+ for rec in self.browse(cr, uid, ids2, context=context):
439+ for child in rec.child_consol_ids:
440+ ids3.append(child.id)
441+ if ids3:
442+ ids3 = self._get_children_and_consol(cr, uid, ids3, context)
443+ return ids2 + ids3
444+
445+ def __compute(self, cr, uid, ids, field_names, arg=None, context=None,
446+ query='', query_params=()):
447+ """ compute the balance, debit and/or credit for the provided
448+ account ids
449+ Arguments:
450+ `ids`: account ids
451+ `field_names`: the fields to compute (a list of any of
452+ 'balance', 'debit' and 'credit')
453+ `arg`: unused fields.function stuff
454+ `query`: additional query filter (as a string)
455+ `query_params`: parameters for the provided query string
456+ (__compute will handle their escaping) as a
457+ tuple
458+ """
459+ mapping = {
460+ 'balance': "COALESCE(SUM(l.debit),0) " \
461+ "- COALESCE(SUM(l.credit), 0) as balance",
462+ 'debit': "COALESCE(SUM(l.debit), 0) as debit",
463+ 'credit': "COALESCE(SUM(l.credit), 0) as credit"
464+ }
465+ #get all the necessary accounts
466+ children_and_consolidated = self._get_children_and_consol(cr, uid, ids, context=context)
467+ #compute for each account the balance/debit/credit from the move lines
468+ accounts = {}
469+ res = {}
470+ null_result = dict((fn, 0.0) for fn in field_names)
471+ if children_and_consolidated:
472+ aml_query = self.pool.get('account.move.line')._query_get(cr, uid, context=context)
473+
474+ wheres = [""]
475+ if query.strip():
476+ wheres.append(query.strip())
477+ if aml_query.strip():
478+ wheres.append(aml_query.strip())
479+ filters = " AND ".join(wheres)
480+ self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG,
481+ 'Filters: %s'%filters)
482+ # IN might not work ideally in case there are too many
483+ # children_and_consolidated, in that case join on a
484+ # values() e.g.:
485+ # SELECT l.account_id as id FROM account_move_line l
486+ # INNER JOIN (VALUES (id1), (id2), (id3), ...) AS tmp (id)
487+ # ON l.account_id = tmp.id
488+ # or make _get_children_and_consol return a query and join on that
489+ request = ("SELECT l.account_id as id, " +\
490+ ', '.join(map(mapping.__getitem__, field_names)) +
491+ " FROM account_move_line l" \
492+ " WHERE l.account_id IN %s " \
493+ + filters +
494+ " GROUP BY l.account_id")
495+ params = (tuple(children_and_consolidated),) + query_params
496+ cr.execute(request, params)
497+ self.logger.notifyChannel('addons.'+self._name, netsvc.LOG_DEBUG,
498+ 'Status: %s'%cr.statusmessage)
499+
500+ for res in cr.dictfetchall():
501+ accounts[res['id']] = res
502+
503+ # consolidate accounts with direct children
504+ children_and_consolidated.reverse()
505+ brs = list(self.browse(cr, uid, children_and_consolidated, context=context))
506+ sums = {}
507+ currency_obj = self.pool.get('res.currency')
508+ while brs:
509+ current = brs[0]
510+# can_compute = True
511+# for child in current.child_id:
512+# if child.id not in sums:
513+# can_compute = False
514+# try:
515+# brs.insert(0, brs.pop(brs.index(child)))
516+# except ValueError:
517+# brs.insert(0, child)
518+# if can_compute:
519+ brs.pop(0)
520+ for fn in field_names:
521+ sums.setdefault(current.id, {})[fn] = accounts.get(current.id, {}).get(fn, 0.0)
522+ for child in current.child_id:
523+ if child.company_id.currency_id.id == current.company_id.currency_id.id:
524+ sums[current.id][fn] += sums[child.id][fn]
525+ else:
526+ 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)
527+ for id in ids:
528+ res[id] = sums.get(id, null_result)
529+ else:
530+ for id in ids:
531+ res[id] = null_result
532+ return res
533+
534+ def _get_company_currency(self, cr, uid, ids, field_name, arg, context=None):
535+ result = {}
536+ for rec in self.browse(cr, uid, ids, context=context):
537+ result[rec.id] = (rec.company_id.currency_id.id,rec.company_id.currency_id.symbol)
538+ return result
539+
540+ def _get_child_ids(self, cr, uid, ids, field_name, arg, context=None):
541+ result = {}
542+ for record in self.browse(cr, uid, ids, context=context):
543+ if record.child_parent_ids:
544+ result[record.id] = [x.id for x in record.child_parent_ids]
545+ else:
546+ result[record.id] = []
547+
548+ if record.child_consol_ids:
549+ for acc in record.child_consol_ids:
550+ if acc.id not in result[record.id]:
551+ result[record.id].append(acc.id)
552+
553+ return result
554+
555+ def _get_level(self, cr, uid, ids, field_name, arg, context=None):
556+ res = {}
557+ accounts = self.browse(cr, uid, ids, context=context)
558+ for account in accounts:
559+ level = 0
560+ if account.parent_id:
561+ obj = self.browse(cr, uid, account.parent_id.id)
562+ level = obj.level + 1
563+ res[account.id] = level
564+ return res
565+
566+ def _set_credit_debit(self, cr, uid, account_id, name, value, arg, context=None):
567+ if context.get('config_invisible', True):
568+ return True
569+
570+ account = self.browse(cr, uid, account_id, context=context)
571+ diff = value - getattr(account,name)
572+ if not diff:
573+ return True
574+
575+ journal_obj = self.pool.get('account.journal')
576+ jids = journal_obj.search(cr, uid, [('type','=','situation'),('centralisation','=',1),('company_id','=',account.company_id.id)], context=context)
577+ if not jids:
578+ raise osv.except_osv(_('Error!'),_("You need an Opening journal with centralisation checked to set the initial balance!"))
579+
580+ period_obj = self.pool.get('account.period')
581+ pids = period_obj.search(cr, uid, [('special','=',True),('company_id','=',account.company_id.id)], context=context)
582+ if not pids:
583+ raise osv.except_osv(_('Error!'),_("No opening/closing period defined, please create one to set the initial balance!"))
584+
585+ move_obj = self.pool.get('account.move.line')
586+ move_id = move_obj.search(cr, uid, [
587+ ('journal_id','=',jids[0]),
588+ ('period_id','=',pids[0]),
589+ ('account_id','=', account_id),
590+ (name,'>', 0.0),
591+ ('name','=', _('Opening Balance'))
592+ ], context=context)
593+ if move_id:
594+ move = move_obj.browse(cr, uid, move_id[0], context=context)
595+ move_obj.write(cr, uid, move_id[0], {
596+ name: diff+getattr(move,name)
597+ }, context=context)
598+ else:
599+ if diff<0.0:
600+ raise osv.except_osv(_('Error!'),_("Unable to adapt the initial balance (negative value)!"))
601+ nameinv = (name=='credit' and 'debit') or 'credit'
602+ move_id = move_obj.create(cr, uid, {
603+ 'name': _('Opening Balance'),
604+ 'account_id': account_id,
605+ 'journal_id': jids[0],
606+ 'period_id': pids[0],
607+ name: diff,
608+ nameinv: 0.0
609+ }, context=context)
610+ return True
611+
612+ _columns = {
613+ 'name': fields.char('Name', size=128, required=True, select=True),
614+ 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
615+ 'code': fields.char('Code', size=64, required=True, select=1),
616+ 'type': fields.selection([
617+ ('view', 'View'),
618+ ('other', 'Regular'),
619+ ('receivable', 'Receivable'),
620+ ('payable', 'Payable'),
621+ ('liquidity','Liquidity'),
622+ ('consolidation', 'Consolidation'),
623+ ('closed', 'Closed'),
624+ ], 'Internal Type', required=True, help="The 'Internal Type' is used for features available on "\
625+ "different types of accounts: view can not have journal items, consolidation are accounts that "\
626+ "can have children accounts for multi-company consolidations, payable/receivable are for "\
627+ "partners accounts (for debit/credit computations), closed for depreciated accounts."),
628+ 'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
629+ help="Account Type is used for information purpose, to generate "
630+ "country-specific legal reports, and set the rules to close a fiscal year and generate opening entries."),
631+ 'parent_id': fields.many2one('account.account', 'Parent', ondelete='cascade', domain=[('type','=','view')]),
632+ 'child_parent_ids': fields.one2many('account.account','parent_id','Children'),
633+ 'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
634+ 'child_id': fields.function(_get_child_ids, type='many2many', relation="account.account", string="Child Accounts"),
635+ 'balance': fields.function(__compute, digits_compute=dp.get_precision('Account'), string='Balance', multi='balance'),
636+ 'credit': fields.function(__compute, fnct_inv=_set_credit_debit, digits_compute=dp.get_precision('Account'), string='Credit', multi='balance'),
637+ 'debit': fields.function(__compute, fnct_inv=_set_credit_debit, digits_compute=dp.get_precision('Account'), string='Debit', multi='balance'),
638+ 'reconcile': fields.boolean('Allow Reconciliation', help="Check this box if this account allows reconciliation of journal items."),
639+ 'shortcut': fields.char('Shortcut', size=12),
640+ 'tax_ids': fields.many2many('account.tax', 'account_account_tax_default_rel',
641+ 'account_id', 'tax_id', 'Default Taxes'),
642+ 'note': fields.text('Note'),
643+ 'company_currency_id': fields.function(_get_company_currency, type='many2one', relation='res.currency', string='Company Currency'),
644+ 'company_id': fields.many2one('res.company', 'Company', required=True),
645+ '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."),
646+
647+ 'parent_left': fields.integer('Parent Left', select=1),
648+ 'parent_right': fields.integer('Parent Right', select=1),
649+ 'currency_mode': fields.selection([('current', 'At Date'), ('average', 'Average Rate')], 'Outgoing Currencies Rate',
650+ help=
651+ 'This will select how the current currency rate for outgoing transactions is computed. '\
652+ 'In most countries the legal method is "average" but only a few software systems are able to '\
653+ 'manage this. So if you import from another software system you may have to use the rate at date. ' \
654+ 'Incoming transactions always use the rate at date.', \
655+ required=True),
656+ 'level': fields.function(_get_level, string='Level', store=True, type='integer'),
657+ }
658+
659+ _defaults = {
660+ 'type': 'view',
661+ 'reconcile': False,
662+ 'active': True,
663+ 'currency_mode': 'current',
664+ 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
665+ }
666+
667+ def _check_recursion(self, cr, uid, ids, context=None):
668+ obj_self = self.browse(cr, uid, ids[0], context=context)
669+ p_id = obj_self.parent_id and obj_self.parent_id.id
670+ if (obj_self in obj_self.child_consol_ids) or (p_id and (p_id is obj_self.id)):
671+ return False
672+ while(ids):
673+ cr.execute('SELECT DISTINCT child_id '\
674+ 'FROM account_account_consol_rel '\
675+ 'WHERE parent_id IN %s', (tuple(ids),))
676+ child_ids = map(itemgetter(0), cr.fetchall())
677+ c_ids = child_ids
678+ if (p_id and (p_id in c_ids)) or (obj_self.id in c_ids):
679+ return False
680+ while len(c_ids):
681+ s_ids = self.search(cr, uid, [('parent_id', 'in', c_ids)])
682+ if p_id and (p_id in s_ids):
683+ return False
684+ c_ids = s_ids
685+ ids = child_ids
686+ return True
687+
688+ def _check_type(self, cr, uid, ids, context=None):
689+ if context is None:
690+ context = {}
691+ accounts = self.browse(cr, uid, ids, context=context)
692+ for account in accounts:
693+ if account.child_id and account.type not in ('view', 'consolidation'):
694+ return False
695+ return True
696+
697+ def _check_account_type(self, cr, uid, ids, context=None):
698+ for account in self.browse(cr, uid, ids, context=context):
699+ if account.type in ('receivable', 'payable') and account.user_type.close_method != 'unreconciled':
700+ return False
701+ return True
702+
703+ _constraints = [
704+ (_check_recursion, 'Error ! You can not create recursive accounts.', ['parent_id']),
705+ (_check_type, 'Configuration Error! \nYou can not define children to an account with internal type different of "View"! ', ['type']),
706+ (_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']),
707+ ]
708+ _sql_constraints = [
709+ ('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !')
710+ ]
711+ def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
712+ if not args:
713+ args = []
714+ args = args[:]
715+ ids = []
716+ try:
717+ if name and str(name).startswith('partner:'):
718+ part_id = int(name.split(':')[1])
719+ part = self.pool.get('res.partner').browse(cr, user, part_id, context=context)
720+ args += [('id', 'in', (part.property_account_payable.id, part.property_account_receivable.id))]
721+ name = False
722+ if name and str(name).startswith('type:'):
723+ type = name.split(':')[1]
724+ args += [('type', '=', type)]
725+ name = False
726+ except:
727+ pass
728+ if name:
729+ ids = self.search(cr, user, [('code', '=like', name+"%")]+args, limit=limit)
730+ if not ids:
731+ ids = self.search(cr, user, [('shortcut', '=', name)]+ args, limit=limit)
732+ if not ids:
733+ ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit)
734+ if not ids and len(name.split()) >= 2:
735+ #Separating code and name of account for searching
736+ operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A.
737+ ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2)]+ args, limit=limit)
738+ else:
739+ ids = self.search(cr, user, args, context=context, limit=limit)
740+ return self.name_get(cr, user, ids, context=context)
741+
742+ def name_get(self, cr, uid, ids, context=None):
743+ if not ids:
744+ return []
745+ reads = self.read(cr, uid, ids, ['name', 'code'], context=context)
746+ res = []
747+ for record in reads:
748+ name = record['name']
749+ if record['code']:
750+ name = record['code'] + ' ' + name
751+ res.append((record['id'], name))
752+ return res
753+
754+ def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False):
755+ account = self.browse(cr, uid, id, context=context)
756+ new_child_ids = []
757+ if not default:
758+ default = {}
759+ default = default.copy()
760+ default['code'] = (account['code'] or '') + '(copy)'
761+ if not local:
762+ done_list = []
763+ if account.id in done_list:
764+ return False
765+ done_list.append(account.id)
766+ if account:
767+ for child in account.child_id:
768+ child_ids = self.copy(cr, uid, child.id, default, context=context, done_list=done_list, local=True)
769+ if child_ids:
770+ new_child_ids.append(child_ids)
771+ default['child_parent_ids'] = [(6, 0, new_child_ids)]
772+ else:
773+ default['child_parent_ids'] = False
774+ return super(account_account, self).copy(cr, uid, id, default, context=context)
775+
776+ def _check_moves(self, cr, uid, ids, method, context=None):
777+ line_obj = self.pool.get('account.move.line')
778+ account_ids = self.search(cr, uid, [('id', 'child_of', ids)])
779+
780+ if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
781+ if method == 'write':
782+ raise osv.except_osv(_('Error !'), _('You can not desactivate an account that contains some journal items.'))
783+ elif method == 'unlink':
784+ raise osv.except_osv(_('Error !'), _('You can not remove an account containing journal items!. '))
785+ #Checking whether the account is set as a property to any Partner or not
786+ value = 'account.account,' + str(ids[0])
787+ partner_prop_acc = self.pool.get('ir.property').search(cr, uid, [('value_reference','=',value)], context=context)
788+ if partner_prop_acc:
789+ raise osv.except_osv(_('Warning !'), _('You can not remove/desactivate an account which is set on a customer or supplier.'))
790+ return True
791+
792+ def _check_allow_type_change(self, cr, uid, ids, new_type, context=None):
793+ group1 = ['payable', 'receivable', 'other']
794+ group2 = ['consolidation','view']
795+ line_obj = self.pool.get('account.move.line')
796+ for account in self.browse(cr, uid, ids, context=context):
797+ old_type = account.type
798+ account_ids = self.search(cr, uid, [('id', 'child_of', [account.id])])
799+ if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
800+ #Check for 'Closed' type
801+ if old_type == 'closed' and new_type !='closed':
802+ raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type which contains journal items!"))
803+ #Check for change From group1 to group2 and vice versa
804+ if (old_type in group1 and new_type in group2) or (old_type in group2 and new_type in group1):
805+ 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,))
806+ return True
807+
808+ def write(self, cr, uid, ids, vals, context=None):
809+
810+ if context is None:
811+ context = {}
812+ if not ids:
813+ return True
814+ if isinstance(ids, (int, long)):
815+ ids = [ids]
816+
817+ # Dont allow changing the company_id when account_move_line already exist
818+ if 'company_id' in vals:
819+ move_lines = self.pool.get('account.move.line').search(cr, uid, [('account_id', 'in', ids)])
820+ if move_lines:
821+ # Allow the write if the value is the same
822+ for i in [i['company_id'][0] for i in self.read(cr,uid,ids,['company_id'])]:
823+ if vals['company_id']!=i:
824+ raise osv.except_osv(_('Warning !'), _('You cannot modify Company of account as its related record exist in Entry Lines'))
825+ if 'active' in vals and not vals['active']:
826+ self._check_moves(cr, uid, ids, "write", context=context)
827+ if 'type' in vals.keys():
828+ self._check_allow_type_change(cr, uid, ids, vals['type'], context=context)
829+ return super(account_account, self).write(cr, uid, ids, vals, context=context)
830+
831+ def unlink(self, cr, uid, ids, context=None):
832+ self._check_moves(cr, uid, ids, "unlink", context=context)
833+ return super(account_account, self).unlink(cr, uid, ids, context=context)
834+
835+account_account()
836+
837+class account_journal_view(osv.osv):
838+ _name = "account.journal.view"
839+ _description = "Journal View"
840+ _columns = {
841+ 'name': fields.char('Journal View', size=64, required=True),
842+ 'columns_id': fields.one2many('account.journal.column', 'view_id', 'Columns')
843+ }
844+ _order = "name"
845+
846+account_journal_view()
847+
848+
849+class account_journal_column(osv.osv):
850+
851+ def _col_get(self, cr, user, context=None):
852+ result = []
853+ cols = self.pool.get('account.move.line')._columns
854+ for col in cols:
855+ if col in ('period_id', 'journal_id'):
856+ continue
857+ result.append( (col, cols[col].string) )
858+ result.sort()
859+ return result
860+
861+ _name = "account.journal.column"
862+ _description = "Journal Column"
863+ _columns = {
864+ 'name': fields.char('Column Name', size=64, required=True),
865+ 'field': fields.selection(_col_get, 'Field Name', required=True, size=32),
866+ 'view_id': fields.many2one('account.journal.view', 'Journal View', select=True),
867+ 'sequence': fields.integer('Sequence', help="Gives the sequence order to journal column.", readonly=True),
868+ 'required': fields.boolean('Required'),
869+ 'readonly': fields.boolean('Readonly'),
870+ }
871+ _order = "view_id, sequence"
872+
873+account_journal_column()
874+
875+class account_journal(osv.osv):
876+ _name = "account.journal"
877+ _description = "Journal"
878+ _columns = {
879+ 'name': fields.char('Journal Name', size=64, required=True),
880+ 'code': fields.char('Code', size=5, required=True, help="The code will be displayed on reports."),
881+ '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,
882+ help="Select 'Sale' for customer invoices journals."\
883+ " Select 'Purchase' for supplier invoices journals."\
884+ " Select 'Cash' or 'Bank' for journals that are used in customer or supplier payments."\
885+ " Select 'General' for miscellaneous operations journals."\
886+ " Select 'Opening/Closing Situation' for entries generated for new fiscal years."),
887+ 'type_control_ids': fields.many2many('account.account.type', 'account_journal_type_rel', 'journal_id','type_id', 'Type Controls', domain=[('code','<>','view'), ('code', '<>', 'closed')]),
888+ 'account_control_ids': fields.many2many('account.account', 'account_account_type_rel', 'journal_id','account_id', 'Account', domain=[('type','<>','view'), ('type', '<>', 'closed')]),
889+ '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."),
890+ 'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account', domain="[('type','!=','view')]", help="It acts as a default account for credit amount"),
891+ 'default_debit_account_id': fields.many2one('account.account', 'Default Debit Account', domain="[('type','!=','view')]", help="It acts as a default account for debit amount"),
892+ '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."),
893+ '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"),
894+ '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."),
895+ '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),
896+ 'user_id': fields.many2one('res.users', 'User', help="The user responsible for this journal"),
897+ 'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'),
898+ 'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'),
899+ '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.'),
900+ 'company_id': fields.many2one('res.company', 'Company', required=True, select=1, help="Company related to this journal"),
901+ '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'),
902+ }
903+
904+ _defaults = {
905+ 'user_id': lambda self, cr, uid, context: uid,
906+ 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
907+ }
908+ _sql_constraints = [
909+ ('code_company_uniq', 'unique (code, company_id)', 'The code of the journal must be unique per company !'),
910+ ('name_company_uniq', 'unique (name, company_id)', 'The name of the journal must be unique per company !'),
911+ ]
912+
913+ _order = 'code'
914+
915+ def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False):
916+ journal = self.browse(cr, uid, id, context=context)
917+ if not default:
918+ default = {}
919+ default = default.copy()
920+ default['code'] = (journal['code'] or '') + '(copy)'
921+ default['name'] = (journal['name'] or '') + '(copy)'
922+ default['sequence_id'] = False
923+ return super(account_journal, self).copy(cr, uid, id, default, context=context)
924+
925+ def write(self, cr, uid, ids, vals, context=None):
926+ if context is None:
927+ context = {}
928+ if isinstance(ids, (int, long)):
929+ ids = [ids]
930+ for journal in self.browse(cr, uid, ids, context=context):
931+ if 'company_id' in vals and journal.company_id.id != vals['company_id']:
932+ move_lines = self.pool.get('account.move.line').search(cr, uid, [('journal_id', 'in', ids)])
933+ if move_lines:
934+ raise osv.except_osv(_('Warning !'), _('You can not modify the company of this journal as its related record exist in journal items'))
935+ return super(account_journal, self).write(cr, uid, ids, vals, context=context)
936+
937+ def create_sequence(self, cr, uid, vals, context=None):
938+ """ Create new no_gap entry sequence for every new Joural
939+ """
940+ # in account.journal code is actually the prefix of the sequence
941+ # whereas ir.sequence code is a key to lookup global sequences.
942+ prefix = vals['code'].upper()
943+
944+ seq = {
945+ 'name': vals['name'],
946+ 'implementation':'no_gap',
947+ 'prefix': prefix + "/%(year)s/",
948+ 'padding': 4,
949+ 'number_increment': 1
950+ }
951+ if 'company_id' in vals:
952+ seq['company_id'] = vals['company_id']
953+ return self.pool.get('ir.sequence').create(cr, uid, seq)
954+
955+ def create(self, cr, uid, vals, context=None):
956+ if not 'sequence_id' in vals or not vals['sequence_id']:
957+ vals.update({'sequence_id': self.create_sequence(cr, uid, vals, context)})
958+ return super(account_journal, self).create(cr, uid, vals, context)
959+
960+ def name_get(self, cr, user, ids, context=None):
961+ """
962+ Returns a list of tupples containing id, name.
963+ result format: {[(id, name), (id, name), ...]}
964+
965+ @param cr: A database cursor
966+ @param user: ID of the user currently logged in
967+ @param ids: list of ids for which name should be read
968+ @param context: context arguments, like lang, time zone
969+
970+ @return: Returns a list of tupples containing id, name
971+ """
972+ result = self.browse(cr, user, ids, context=context)
973+ res = []
974+ for rs in result:
975+ name = rs.name
976+ if rs.currency:
977+ name = "%s (%s)" % (rs.name, rs.currency.name)
978+ res += [(rs.id, name)]
979+ return res
980+
981+ def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
982+ if not args:
983+ args = []
984+ if context is None:
985+ context = {}
986+ ids = []
987+ if context.get('journal_type', False):
988+ args += [('type','=',context.get('journal_type'))]
989+ if name:
990+ ids = self.search(cr, user, [('code', 'ilike', name)]+ args, limit=limit, context=context)
991+ if not ids:
992+ ids = self.search(cr, user, [('name', 'ilike', name)]+ args, limit=limit, context=context)#fix it ilike should be replace with operator
993+
994+ return self.name_get(cr, user, ids, context=context)
995+
996+ def onchange_type(self, cr, uid, ids, type, currency, context=None):
997+ obj_data = self.pool.get('ir.model.data')
998+ user_pool = self.pool.get('res.users')
999+
1000+ type_map = {
1001+ 'sale':'account_sp_journal_view',
1002+ 'sale_refund':'account_sp_refund_journal_view',
1003+ 'purchase':'account_sp_journal_view',
1004+ 'purchase_refund':'account_sp_refund_journal_view',
1005+ 'cash':'account_journal_bank_view',
1006+ 'bank':'account_journal_bank_view',
1007+ 'general':'account_journal_view',
1008+ 'situation':'account_journal_view'
1009+ }
1010+
1011+ res = {}
1012+ view_id = type_map.get(type, 'account_journal_view')
1013+ user = user_pool.browse(cr, uid, uid)
1014+ if type in ('cash', 'bank') and currency and user.company_id.currency_id.id != currency:
1015+ view_id = 'account_journal_bank_view_multi'
1016+ data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=',view_id)])
1017+ data = obj_data.browse(cr, uid, data_id[0], context=context)
1018+
1019+ res.update({
1020+ 'centralisation':type == 'situation',
1021+ 'view_id':data.res_id,
1022+ })
1023+ return {
1024+ 'value':res
1025+ }
1026+
1027+account_journal()
1028+
1029+class account_fiscalyear(osv.osv):
1030+ _name = "account.fiscalyear"
1031+ _description = "Fiscal Year"
1032+ _columns = {
1033+ 'name': fields.char('Fiscal Year', size=64, required=True),
1034+ 'code': fields.char('Code', size=6, required=True),
1035+ 'company_id': fields.many2one('res.company', 'Company', required=True),
1036+ 'date_start': fields.date('Start Date', required=True),
1037+ 'date_stop': fields.date('End Date', required=True),
1038+ 'period_ids': fields.one2many('account.period', 'fiscalyear_id', 'Periods'),
1039+ 'state': fields.selection([('draft','Open'), ('done','Closed')], 'State', readonly=True),
1040+ }
1041+ _defaults = {
1042+ 'state': 'draft',
1043+ 'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
1044+ }
1045+ _order = "date_start"
1046+
1047+ def _check_fiscal_year(self, cr, uid, ids, context=None):
1048+ current_fiscal_yr = self.browse(cr, uid, ids, context=context)[0]
1049+ obj_fiscal_ids = self.search(cr, uid, [('company_id', '=', current_fiscal_yr.company_id.id)], context=context)
1050+ obj_fiscal_ids.remove(ids[0])
1051+ data_fiscal_yr = self.browse(cr, uid, obj_fiscal_ids, context=context)
1052+
1053+ for old_fy in data_fiscal_yr:
1054+ if old_fy.company_id.id == current_fiscal_yr['company_id'].id:
1055+ # Condition to check if the current fiscal year falls in between any previously defined fiscal year
1056+ if old_fy.date_start <= current_fiscal_yr['date_start'] <= old_fy.date_stop or \
1057+ old_fy.date_start <= current_fiscal_yr['date_stop'] <= old_fy.date_stop:
1058+ return False
1059+ return True
1060+
1061+ def _check_duration(self, cr, uid, ids, context=None):
1062+ obj_fy = self.browse(cr, uid, ids[0], context=context)
1063+ if obj_fy.date_stop < obj_fy.date_start:
1064+ return False
1065+ return True
1066+
1067+ _constraints = [
1068+ (_check_duration, 'Error! The start date of the fiscal year must be before his end date.', ['date_start','date_stop']),
1069+ (_check_fiscal_year, 'Error! You can not define overlapping fiscal years for the same company.',['date_start', 'date_stop'])
1070+ ]
1071+
1072+ def create_period3(self, cr, uid, ids, context=None):
1073+ return self.create_period(cr, uid, ids, context, 3)
1074+
1075+ def create_period(self, cr, uid, ids, context=None, interval=1):
1076+ period_obj = self.pool.get('account.period')
1077+ for fy in self.browse(cr, uid, ids, context=context):
1078+ ds = datetime.strptime(fy.date_start, '%Y-%m-%d')
1079+ period_obj.create(cr, uid, {
1080+ 'name': _('Opening Period'),
1081+ 'code': ds.strftime('00/%Y'),
1082+ 'date_start': ds,
1083+ 'date_stop': ds,
1084+ 'special': True,
1085+ 'fiscalyear_id': fy.id,
1086+ })
1087+ while ds.strftime('%Y-%m-%d') < fy.date_stop:
1088+ de = ds + relativedelta(months=interval, days=-1)
1089+
1090+ if de.strftime('%Y-%m-%d') > fy.date_stop:
1091+ de = datetime.strptime(fy.date_stop, '%Y-%m-%d')
1092+
1093+ period_obj.create(cr, uid, {
1094+ 'name': ds.strftime('%m/%Y'),
1095+ 'code': ds.strftime('%m/%Y'),
1096+ 'date_start': ds.strftime('%Y-%m-%d'),
1097+ 'date_stop': de.strftime('%Y-%m-%d'),
1098+ 'fiscalyear_id': fy.id,
1099+ })
1100+ ds = ds + relativedelta(months=interval)
1101+ return True
1102+
1103+ def find(self, cr, uid, dt=None, exception=True, context=None):
1104+ if not dt:
1105+ dt = time.strftime('%Y-%m-%d')
1106+ ids = self.search(cr, uid, [('date_start', '<=', dt), ('date_stop', '>=', dt)])
1107+ if not ids:
1108+ if exception:
1109+ raise osv.except_osv(_('Error !'), _('No fiscal year defined for this date !\nPlease create one.'))
1110+ else:
1111+ return False
1112+ return ids[0]
1113+
1114+ def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
1115+ if args is None:
1116+ args = []
1117+ if context is None:
1118+ context = {}
1119+ ids = []
1120+ if name:
1121+ ids = self.search(cr, user, [('code', 'ilike', name)]+ args, limit=limit)
1122+ if not ids:
1123+ ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit)
1124+ return self.name_get(cr, user, ids, context=context)
1125+
1126+account_fiscalyear()
1127+
1128+class account_period(osv.osv):
1129+ _name = "account.period"
1130+ _description = "Account period"
1131+ _columns = {
1132+ 'name': fields.char('Period Name', size=64, required=True),
1133+ 'code': fields.char('Code', size=12),
1134+ 'special': fields.boolean('Opening/Closing Period', size=12,
1135+ help="These periods can overlap."),
1136+ 'date_start': fields.date('Start of Period', required=True, states={'done':[('readonly',True)]}),
1137+ 'date_stop': fields.date('End of Period', required=True, states={'done':[('readonly',True)]}),
1138+ 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True),
1139+ 'state': fields.selection([('draft','Open'), ('done','Closed')], 'State', readonly=True,
1140+ help='When monthly periods are created. The state is \'Draft\'. At the end of monthly period it is in \'Done\' state.'),
1141+ 'company_id': fields.related('fiscalyear_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
1142+ }
1143+ _defaults = {
1144+ 'state': 'draft',
1145+ }
1146+ _order = "date_start, special desc"
1147+ _sql_constraints = [
1148+ ('name_company_uniq', 'unique(name, company_id)', 'The name of the period must be unique per company!'),
1149+ ]
1150+
1151+ def _check_duration(self,cr,uid,ids,context=None):
1152+ obj_period = self.browse(cr, uid, ids[0], context=context)
1153+ if obj_period.date_stop < obj_period.date_start:
1154+ return False
1155+ return True
1156+
1157+ def _check_year_limit(self,cr,uid,ids,context=None):
1158+ for obj_period in self.browse(cr, uid, ids, context=context):
1159+ if obj_period.special:
1160+ continue
1161+
1162+ if obj_period.fiscalyear_id.date_stop < obj_period.date_stop or \
1163+ obj_period.fiscalyear_id.date_stop < obj_period.date_start or \
1164+ obj_period.fiscalyear_id.date_start > obj_period.date_start or \
1165+ obj_period.fiscalyear_id.date_start > obj_period.date_stop:
1166+ return False
1167+
1168+ pids = self.search(cr, uid, [('date_stop','>=',obj_period.date_start),('date_start','<=',obj_period.date_stop),('special','=',False),('id','<>',obj_period.id)])
1169+ for period in self.browse(cr, uid, pids):
1170+ if period.fiscalyear_id.company_id.id==obj_period.fiscalyear_id.company_id.id:
1171+ return False
1172+ return True
1173+
1174+ _constraints = [
1175+ (_check_duration, 'Error ! The duration of the Period(s) is/are invalid. ', ['date_stop']),
1176+ (_check_year_limit, 'Invalid period ! Some periods overlap or the date period is not in the scope of the fiscal year. ', ['date_stop'])
1177+ ]
1178+
1179+ def next(self, cr, uid, period, step, context=None):
1180+ ids = self.search(cr, uid, [('date_start','>',period.date_start)])
1181+ if len(ids)>=step:
1182+ return ids[step-1]
1183+ return False
1184+
1185+ def find(self, cr, uid, dt=None, context=None):
1186+ if not dt:
1187+ dt = time.strftime('%Y-%m-%d')
1188+#CHECKME: shouldn't we check the state of the period?
1189+ ids = self.search(cr, uid, [('date_start','<=',dt),('date_stop','>=',dt)])
1190+ if not ids:
1191+ raise osv.except_osv(_('Error !'), _('No period defined for this date: %s !\nPlease create one.')%dt)
1192+ return ids
1193+
1194+ def action_draft(self, cr, uid, ids, *args):
1195+ mode = 'draft'
1196+ cr.execute('update account_journal_period set state=%s where period_id in %s', (mode, tuple(ids),))
1197+ cr.execute('update account_period set state=%s where id in %s', (mode, tuple(ids),))
1198+ return True
1199+
1200+ def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
1201+ if args is None:
1202+ args = []
1203+ if context is None:
1204+ context = {}
1205+ ids = []
1206+ if name:
1207+ ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit)
1208+ if not ids:
1209+ ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
1210+ return self.name_get(cr, user, ids, context=context)
1211+
1212+ def write(self, cr, uid, ids, vals, context=None):
1213+ if 'company_id' in vals:
1214+ move_lines = self.pool.get('account.move.line').search(cr, uid, [('period_id', 'in', ids)])
1215+ if move_lines:
1216+ raise osv.except_osv(_('Warning !'), _('You can not modify company of this period as some journal items exists.'))
1217+ return super(account_period, self).write(cr, uid, ids, vals, context=context)
1218+
1219+ def build_ctx_periods(self, cr, uid, period_from_id, period_to_id):
1220+ period_from = self.browse(cr, uid, period_from_id)
1221+ period_date_start = period_from.date_start
1222+ company1_id = period_from.company_id.id
1223+ period_to = self.browse(cr, uid, period_to_id)
1224+ period_date_stop = period_to.date_stop
1225+ company2_id = period_to.company_id.id
1226+ if company1_id != company2_id:
1227+ raise osv.except_osv(_('Error'), _('You should have chosen periods that belongs to the same company'))
1228+ if period_date_start > period_date_stop:
1229+ raise osv.except_osv(_('Error'), _('Start period should be smaller then End period'))
1230+ #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).
1231+ if period_from.special:
1232+ return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id)])
1233+ return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id), ('special', '=', False)])
1234+
1235+account_period()
1236+
1237+class account_journal_period(osv.osv):
1238+ _name = "account.journal.period"
1239+ _description = "Journal Period"
1240+
1241+ def _icon_get(self, cr, uid, ids, field_name, arg=None, context=None):
1242+ result = {}.fromkeys(ids, 'STOCK_NEW')
1243+ for r in self.read(cr, uid, ids, ['state']):
1244+ result[r['id']] = {
1245+ 'draft': 'STOCK_NEW',
1246+ 'printed': 'STOCK_PRINT_PREVIEW',
1247+ 'done': 'STOCK_DIALOG_AUTHENTICATION',
1248+ }.get(r['state'], 'STOCK_NEW')
1249+ return result
1250+
1251+ _columns = {
1252+ 'name': fields.char('Journal-Period Name', size=64, required=True),
1253+ 'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade"),
1254+ 'period_id': fields.many2one('account.period', 'Period', required=True, ondelete="cascade"),
1255+ 'icon': fields.function(_icon_get, string='Icon', type='char', size=32),
1256+ '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."),
1257+ 'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'State', required=True, readonly=True,
1258+ 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.'),
1259+ 'fiscalyear_id': fields.related('period_id', 'fiscalyear_id', string='Fiscal Year', type='many2one', relation='account.fiscalyear'),
1260+ 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
1261+ }
1262+
1263+ def _check(self, cr, uid, ids, context=None):
1264+ for obj in self.browse(cr, uid, ids, context=context):
1265+ 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))
1266+ res = cr.fetchall()
1267+ if res:
1268+ raise osv.except_osv(_('Error !'), _('You can not modify/delete a journal with entries for this period !'))
1269+ return True
1270+
1271+ def write(self, cr, uid, ids, vals, context=None):
1272+ self._check(cr, uid, ids, context=context)
1273+ return super(account_journal_period, self).write(cr, uid, ids, vals, context=context)
1274+
1275+ def create(self, cr, uid, vals, context=None):
1276+ period_id = vals.get('period_id',False)
1277+ if period_id:
1278+ period = self.pool.get('account.period').browse(cr, uid, period_id, context=context)
1279+ vals['state']=period.state
1280+ return super(account_journal_period, self).create(cr, uid, vals, context)
1281+
1282+ def unlink(self, cr, uid, ids, context=None):
1283+ self._check(cr, uid, ids, context=context)
1284+ return super(account_journal_period, self).unlink(cr, uid, ids, context=context)
1285+
1286+ _defaults = {
1287+ 'state': 'draft',
1288+ 'active': True,
1289+ }
1290+ _order = "period_id"
1291+
1292+account_journal_period()
1293+
1294+class account_fiscalyear(osv.osv):
1295+ _inherit = "account.fiscalyear"
1296+ _description = "Fiscal Year"
1297+ _columns = {
1298+ 'end_journal_period_id':fields.many2one('account.journal.period','End of Year Entries Journal', readonly=True),
1299+ }
1300+
1301+ def copy(self, cr, uid, id, default={}, context=None):
1302+ default.update({
1303+ 'period_ids': [],
1304+ 'end_journal_period_id': False
1305+ })
1306+ return super(account_fiscalyear, self).copy(cr, uid, id, default=default, context=context)
1307+
1308+account_fiscalyear()
1309+#----------------------------------------------------------
1310+# Entries
1311+#----------------------------------------------------------
1312+class account_move(osv.osv):
1313+ _name = "account.move"
1314+ _description = "Account Entry"
1315+ _order = 'id desc'
1316+
1317+ def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
1318+ """
1319+ Returns a list of tupples containing id, name, as internally it is called {def name_get}
1320+ result format: {[(id, name), (id, name), ...]}
1321+
1322+ @param cr: A database cursor
1323+ @param user: ID of the user currently logged in
1324+ @param name: name to search
1325+ @param args: other arguments
1326+ @param operator: default operator is 'ilike', it can be changed
1327+ @param context: context arguments, like lang, time zone
1328+ @param limit: Returns first 'n' ids of complete result, default is 80.
1329+
1330+ @return: Returns a list of tuples containing id and name
1331+ """
1332+
1333+ if not args:
1334+ args = []
1335+ ids = []
1336+ if name:
1337+ ids += self.search(cr, user, [('name','ilike',name)]+args, limit=limit, context=context)
1338+
1339+ if not ids and name and type(name) == int:
1340+ ids += self.search(cr, user, [('id','=',name)]+args, limit=limit, context=context)
1341+
1342+ if not ids:
1343+ ids += self.search(cr, user, args, limit=limit, context=context)
1344+
1345+ return self.name_get(cr, user, ids, context=context)
1346+
1347+ def name_get(self, cursor, user, ids, context=None):
1348+ if isinstance(ids, (int, long)):
1349+ ids = [ids]
1350+ if not ids:
1351+ return []
1352+ res = []
1353+ data_move = self.pool.get('account.move').browse(cursor, user, ids, context=context)
1354+ for move in data_move:
1355+ if move.state=='draft':
1356+ name = '*' + str(move.id)
1357+ else:
1358+ name = move.name
1359+ res.append((move.id, name))
1360+ return res
1361+
1362+ def _get_period(self, cr, uid, context=None):
1363+ periods = self.pool.get('account.period').find(cr, uid)
1364+ if periods:
1365+ return periods[0]
1366+ return False
1367+
1368+ def _amount_compute(self, cr, uid, ids, name, args, context, where =''):
1369+ if not ids: return {}
1370+ cr.execute( 'SELECT move_id, SUM(debit) '\
1371+ 'FROM account_move_line '\
1372+ 'WHERE move_id IN %s '\
1373+ 'GROUP BY move_id', (tuple(ids),))
1374+ result = dict(cr.fetchall())
1375+ for id in ids:
1376+ result.setdefault(id, 0.0)
1377+ return result
1378+
1379+ def _search_amount(self, cr, uid, obj, name, args, context):
1380+ ids = set()
1381+ for cond in args:
1382+ amount = cond[2]
1383+ if isinstance(cond[2],(list,tuple)):
1384+ if cond[1] in ['in','not in']:
1385+ amount = tuple(cond[2])
1386+ else:
1387+ continue
1388+ else:
1389+ if cond[1] in ['=like', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of']:
1390+ continue
1391+
1392+ cr.execute("select move_id from account_move_line group by move_id having sum(debit) %s %%s" % (cond[1]),(amount,))
1393+ res_ids = set(id[0] for id in cr.fetchall())
1394+ ids = ids and (ids & res_ids) or res_ids
1395+ if ids:
1396+ return [('id', 'in', tuple(ids))]
1397+ return [('id', '=', '0')]
1398+
1399+ _columns = {
1400+ 'name': fields.char('Number', size=64, required=True),
1401+ 'ref': fields.char('Reference', size=64),
1402+ 'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
1403+ 'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
1404+ 'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'State', required=True, readonly=True,
1405+ 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.'),
1406+ 'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
1407+ '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.'),
1408+ 'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
1409+ 'amount': fields.function(_amount_compute, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount),
1410+ 'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}, select=True),
1411+ 'narration':fields.text('Internal Note'),
1412+ 'company_id': fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
1413+ }
1414+ _defaults = {
1415+ 'name': '/',
1416+ 'state': 'draft',
1417+ 'period_id': _get_period,
1418+ 'date': lambda *a: time.strftime('%Y-%m-%d'),
1419+ 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
1420+ }
1421+
1422+ def _check_centralisation(self, cursor, user, ids, context=None):
1423+ for move in self.browse(cursor, user, ids, context=context):
1424+ if move.journal_id.centralisation:
1425+ move_ids = self.search(cursor, user, [
1426+ ('period_id', '=', move.period_id.id),
1427+ ('journal_id', '=', move.journal_id.id),
1428+ ])
1429+ if len(move_ids) > 1:
1430+ return False
1431+ return True
1432+
1433+ def _check_period_journal(self, cursor, user, ids, context=None):
1434+ for move in self.browse(cursor, user, ids, context=context):
1435+ for line in move.line_id:
1436+ if line.period_id.id != move.period_id.id:
1437+ return False
1438+ if line.journal_id.id != move.journal_id.id:
1439+ return False
1440+ return True
1441+
1442+ _constraints = [
1443+ (_check_centralisation,
1444+ 'You can not create more than one move per period on centralized journal',
1445+ ['journal_id']),
1446+ (_check_period_journal,
1447+ 'You can not create journal items on different periods/journals in the same journal entry',
1448+ ['line_id']),
1449+ ]
1450+
1451+ def post(self, cr, uid, ids, context=None):
1452+ if context is None:
1453+ context = {}
1454+ invoice = context.get('invoice', False)
1455+ valid_moves = self.validate(cr, uid, ids, context)
1456+
1457+ if not valid_moves:
1458+ 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" !'))
1459+ obj_sequence = self.pool.get('ir.sequence')
1460+ for move in self.browse(cr, uid, valid_moves, context=context):
1461+ if move.name =='/':
1462+ new_name = False
1463+ journal = move.journal_id
1464+
1465+ if invoice and invoice.internal_number:
1466+ new_name = invoice.internal_number
1467+ else:
1468+ if journal.sequence_id:
1469+ c = {'fiscalyear_id': move.period_id.fiscalyear_id.id}
1470+ new_name = obj_sequence.next_by_id(cr, uid, journal.sequence_id.id, c)
1471+ else:
1472+ raise osv.except_osv(_('Error'), _('No sequence defined on the journal !'))
1473+
1474+ if new_name:
1475+ self.write(cr, uid, [move.id], {'name':new_name})
1476+
1477+ cr.execute('UPDATE account_move '\
1478+ 'SET state=%s '\
1479+ 'WHERE id IN %s',
1480+ ('posted', tuple(valid_moves),))
1481+ return True
1482+
1483+ def button_validate(self, cursor, user, ids, context=None):
1484+ for move in self.browse(cursor, user, ids, context=context):
1485+ top = None
1486+ for line in move.line_id:
1487+ account = line.account_id
1488+ while account:
1489+ account2 = account
1490+ account = account.parent_id
1491+ if not top:
1492+ top = account2.id
1493+ elif top<>account2.id:
1494+ raise osv.except_osv(_('Error !'), _('You can not validate a journal entry unless all journal items belongs to the same chart of accounts !'))
1495+ return self.post(cursor, user, ids, context=context)
1496+
1497+ def button_cancel(self, cr, uid, ids, context=None):
1498+ for line in self.browse(cr, uid, ids, context=context):
1499+ if not line.journal_id.update_posted:
1500+ 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.'))
1501+ if ids:
1502+ cr.execute('UPDATE account_move '\
1503+ 'SET state=%s '\
1504+ 'WHERE id IN %s', ('draft', tuple(ids),))
1505+ return True
1506+
1507+ def write(self, cr, uid, ids, vals, context=None):
1508+ if context is None:
1509+ context = {}
1510+ c = context.copy()
1511+ c['novalidate'] = True
1512+ result = super(account_move, self).write(cr, uid, ids, vals, c)
1513+ self.validate(cr, uid, ids, context=context)
1514+ return result
1515+
1516+ #
1517+ # TODO: Check if period is closed !
1518+ #
1519+ def create(self, cr, uid, vals, context=None):
1520+ if context is None:
1521+ context = {}
1522+ if 'line_id' in vals and context.get('copy'):
1523+ for l in vals['line_id']:
1524+ if not l[0]:
1525+ l[2].update({
1526+ 'reconcile_id':False,
1527+ 'reconcil_partial_id':False,
1528+ 'analytic_lines':False,
1529+ 'invoice':False,
1530+ 'ref':False,
1531+ 'balance':False,
1532+ 'account_tax_id':False,
1533+ })
1534+
1535+ if 'journal_id' in vals and vals.get('journal_id', False):
1536+ for l in vals['line_id']:
1537+ if not l[0]:
1538+ l[2]['journal_id'] = vals['journal_id']
1539+ context['journal_id'] = vals['journal_id']
1540+ if 'period_id' in vals:
1541+ for l in vals['line_id']:
1542+ if not l[0]:
1543+ l[2]['period_id'] = vals['period_id']
1544+ context['period_id'] = vals['period_id']
1545+ else:
1546+ default_period = self._get_period(cr, uid, context)
1547+ for l in vals['line_id']:
1548+ if not l[0]:
1549+ l[2]['period_id'] = default_period
1550+ context['period_id'] = default_period
1551+
1552+ if 'line_id' in vals:
1553+ c = context.copy()
1554+ c['novalidate'] = True
1555+ result = super(account_move, self).create(cr, uid, vals, c)
1556+ self.validate(cr, uid, [result], context)
1557+ else:
1558+ result = super(account_move, self).create(cr, uid, vals, context)
1559+ return result
1560+
1561+ def copy(self, cr, uid, id, default={}, context=None):
1562+ if context is None:
1563+ context = {}
1564+ default.update({
1565+ 'state':'draft',
1566+ 'name':'/',
1567+ })
1568+ context.update({
1569+ 'copy':True
1570+ })
1571+ return super(account_move, self).copy(cr, uid, id, default, context)
1572+
1573+ def unlink(self, cr, uid, ids, context=None, check=True):
1574+ if context is None:
1575+ context = {}
1576+ toremove = []
1577+ obj_move_line = self.pool.get('account.move.line')
1578+ for move in self.browse(cr, uid, ids, context=context):
1579+ if move['state'] != 'draft':
1580+ raise osv.except_osv(_('UserError'),
1581+ _('You can not delete a posted journal entry "%s"!') % \
1582+ move['name'])
1583+ line_ids = map(lambda x: x.id, move.line_id)
1584+ context['journal_id'] = move.journal_id.id
1585+ context['period_id'] = move.period_id.id
1586+ obj_move_line._update_check(cr, uid, line_ids, context)
1587+ obj_move_line.unlink(cr, uid, line_ids, context=context)
1588+ toremove.append(move.id)
1589+ result = super(account_move, self).unlink(cr, uid, toremove, context)
1590+ return result
1591+
1592+ def _compute_balance(self, cr, uid, id, context=None):
1593+ move = self.browse(cr, uid, id, context=context)
1594+ amount = 0
1595+ for line in move.line_id:
1596+ amount+= (line.debit - line.credit)
1597+ return amount
1598+
1599+ def _centralise(self, cr, uid, move, mode, context=None):
1600+ assert mode in ('debit', 'credit'), 'Invalid Mode' #to prevent sql injection
1601+ currency_obj = self.pool.get('res.currency')
1602+ if context is None:
1603+ context = {}
1604+
1605+ if mode=='credit':
1606+ account_id = move.journal_id.default_debit_account_id.id
1607+ mode2 = 'debit'
1608+ if not account_id:
1609+ raise osv.except_osv(_('UserError'),
1610+ _('There is no default default debit account defined \n' \
1611+ 'on journal "%s"') % move.journal_id.name)
1612+ else:
1613+ account_id = move.journal_id.default_credit_account_id.id
1614+ mode2 = 'credit'
1615+ if not account_id:
1616+ raise osv.except_osv(_('UserError'),
1617+ _('There is no default default credit account defined \n' \
1618+ 'on journal "%s"') % move.journal_id.name)
1619+
1620+ # find the first line of this move with the current mode
1621+ # or create it if it doesn't exist
1622+ cr.execute('select id from account_move_line where move_id=%s and centralisation=%s limit 1', (move.id, mode))
1623+ res = cr.fetchone()
1624+ if res:
1625+ line_id = res[0]
1626+ else:
1627+ context.update({'journal_id': move.journal_id.id, 'period_id': move.period_id.id})
1628+ line_id = self.pool.get('account.move.line').create(cr, uid, {
1629+ 'name': _(mode.capitalize()+' Centralisation'),
1630+ 'centralisation': mode,
1631+ 'account_id': account_id,
1632+ 'move_id': move.id,
1633+ 'journal_id': move.journal_id.id,
1634+ 'period_id': move.period_id.id,
1635+ 'date': move.period_id.date_stop,
1636+ 'debit': 0.0,
1637+ 'credit': 0.0,
1638+ }, context)
1639+
1640+ # find the first line of this move with the other mode
1641+ # so that we can exclude it from our calculation
1642+ cr.execute('select id from account_move_line where move_id=%s and centralisation=%s limit 1', (move.id, mode2))
1643+ res = cr.fetchone()
1644+ if res:
1645+ line_id2 = res[0]
1646+ else:
1647+ line_id2 = 0
1648+
1649+ cr.execute('SELECT SUM(%s) FROM account_move_line WHERE move_id=%%s AND id!=%%s' % (mode,), (move.id, line_id2))
1650+ result = cr.fetchone()[0] or 0.0
1651+ cr.execute('update account_move_line set '+mode2+'=%s where id=%s', (result, line_id))
1652+
1653+ #adjust also the amount in currency if needed
1654+ 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,))
1655+ for row in cr.dictfetchall():
1656+ currency_id = currency_obj.browse(cr, uid, row['currency_id'], context=context)
1657+ if not currency_obj.is_zero(cr, uid, currency_id, row['amount_currency']):
1658+ amount_currency = row['amount_currency'] * -1
1659+ account_id = amount_currency > 0 and move.journal_id.default_debit_account_id.id or move.journal_id.default_credit_account_id.id
1660+ 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']))
1661+ res = cr.fetchone()
1662+ if res:
1663+ cr.execute('update account_move_line set amount_currency=%s , account_id=%s where id=%s', (amount_currency, account_id, res[0]))
1664+ else:
1665+ context.update({'journal_id': move.journal_id.id, 'period_id': move.period_id.id})
1666+ line_id = self.pool.get('account.move.line').create(cr, uid, {
1667+ 'name': _('Currency Adjustment'),
1668+ 'centralisation': 'currency',
1669+ 'account_id': account_id,
1670+ 'move_id': move.id,
1671+ 'journal_id': move.journal_id.id,
1672+ 'period_id': move.period_id.id,
1673+ 'date': move.period_id.date_stop,
1674+ 'debit': 0.0,
1675+ 'credit': 0.0,
1676+ 'currency_id': row['currency_id'],
1677+ 'amount_currency': amount_currency,
1678+ }, context)
1679+
1680+ return True
1681+
1682+ #
1683+ # Validate a balanced move. If it is a centralised journal, create a move.
1684+ #
1685+ def validate(self, cr, uid, ids, context=None):
1686+ if context and ('__last_update' in context):
1687+ del context['__last_update']
1688+
1689+ valid_moves = [] #Maintains a list of moves which can be responsible to create analytic entries
1690+ obj_analytic_line = self.pool.get('account.analytic.line')
1691+ obj_move_line = self.pool.get('account.move.line')
1692+ for move in self.browse(cr, uid, ids, context):
1693+ # Unlink old analytic lines on move_lines
1694+ for obj_line in move.line_id:
1695+ for obj in obj_line.analytic_lines:
1696+ obj_analytic_line.unlink(cr,uid,obj.id)
1697+
1698+ journal = move.journal_id
1699+ amount = 0
1700+ line_ids = []
1701+ line_draft_ids = []
1702+ company_id = None
1703+ for line in move.line_id:
1704+ amount += line.debit - line.credit
1705+ line_ids.append(line.id)
1706+ if line.state=='draft':
1707+ line_draft_ids.append(line.id)
1708+
1709+ if not company_id:
1710+ company_id = line.account_id.company_id.id
1711+ if not company_id == line.account_id.company_id.id:
1712+ raise osv.except_osv(_('Error'), _("Couldn't create move between different companies"))
1713+
1714+ if line.account_id.currency_id and line.currency_id:
1715+ 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):
1716+ 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))
1717+
1718+ if abs(amount) < 10 ** -4:
1719+ # If the move is balanced
1720+ # Add to the list of valid moves
1721+ # (analytic lines will be created later for valid moves)
1722+ valid_moves.append(move)
1723+
1724+ # Check whether the move lines are confirmed
1725+
1726+ if not line_draft_ids:
1727+ continue
1728+ # Update the move lines (set them as valid)
1729+
1730+ obj_move_line.write(cr, uid, line_draft_ids, {
1731+ 'journal_id': move.journal_id.id,
1732+ 'period_id': move.period_id.id,
1733+ 'state': 'valid'
1734+ }, context, check=False)
1735+
1736+ account = {}
1737+ account2 = {}
1738+
1739+ if journal.type in ('purchase','sale'):
1740+ for line in move.line_id:
1741+ code = amount = 0
1742+ key = (line.account_id.id, line.tax_code_id.id)
1743+ if key in account2:
1744+ code = account2[key][0]
1745+ amount = account2[key][1] * (line.debit + line.credit)
1746+ elif line.account_id.id in account:
1747+ code = account[line.account_id.id][0]
1748+ amount = account[line.account_id.id][1] * (line.debit + line.credit)
1749+ if (code or amount) and not (line.tax_code_id or line.tax_amount):
1750+ obj_move_line.write(cr, uid, [line.id], {
1751+ 'tax_code_id': code,
1752+ 'tax_amount': amount
1753+ }, context, check=False)
1754+ elif journal.centralisation:
1755+ # If the move is not balanced, it must be centralised...
1756+
1757+ # Add to the list of valid moves
1758+ # (analytic lines will be created later for valid moves)
1759+ valid_moves.append(move)
1760+
1761+ #
1762+ # Update the move lines (set them as valid)
1763+ #
1764+ self._centralise(cr, uid, move, 'debit', context=context)
1765+ self._centralise(cr, uid, move, 'credit', context=context)
1766+ obj_move_line.write(cr, uid, line_draft_ids, {
1767+ 'state': 'valid'
1768+ }, context, check=False)
1769+ else:
1770+ # We can't validate it (it's unbalanced)
1771+ # Setting the lines as draft
1772+ obj_move_line.write(cr, uid, line_ids, {
1773+ 'journal_id': move.journal_id.id,
1774+ 'period_id': move.period_id.id,
1775+ 'state': 'draft'
1776+ }, context, check=False)
1777+ # Create analytic lines for the valid moves
1778+ for record in valid_moves:
1779+ obj_move_line.create_analytic_lines(cr, uid, [line.id for line in record.line_id], context)
1780+
1781+ valid_moves = [move.id for move in valid_moves]
1782+ return len(valid_moves) > 0 and valid_moves or False
1783+
1784+account_move()
1785+
1786+class account_move_reconcile(osv.osv):
1787+ _name = "account.move.reconcile"
1788+ _description = "Account Reconciliation"
1789+ _columns = {
1790+ 'name': fields.char('Name', size=64, required=True),
1791+ 'type': fields.char('Type', size=16, required=True),
1792+ 'line_id': fields.one2many('account.move.line', 'reconcile_id', 'Entry Lines'),
1793+ 'line_partial_ids': fields.one2many('account.move.line', 'reconcile_partial_id', 'Partial Entry lines'),
1794+ 'create_date': fields.date('Creation date', readonly=True),
1795+ }
1796+ _defaults = {
1797+ 'name': lambda self,cr,uid,ctx={}: self.pool.get('ir.sequence').get(cr, uid, 'account.reconcile') or '/',
1798+ }
1799+ def reconcile_partial_check(self, cr, uid, ids, type='auto', context=None):
1800+ total = 0.0
1801+ for rec in self.browse(cr, uid, ids, context=context):
1802+ for line in rec.line_partial_ids:
1803+ total += (line.debit or 0.0) - (line.credit or 0.0)
1804+ if not total:
1805+ self.pool.get('account.move.line').write(cr, uid,
1806+ map(lambda x: x.id, rec.line_partial_ids),
1807+ {'reconcile_id': rec.id }
1808+ )
1809+ return True
1810+
1811+ def name_get(self, cr, uid, ids, context=None):
1812+ if not ids:
1813+ return []
1814+ result = []
1815+ for r in self.browse(cr, uid, ids, context=context):
1816+ total = reduce(lambda y,t: (t.debit or 0.0) - (t.credit or 0.0) + y, r.line_partial_ids, 0.0)
1817+ if total:
1818+ name = '%s (%.2f)' % (r.name, total)
1819+ result.append((r.id,name))
1820+ else:
1821+ result.append((r.id,r.name))
1822+ return result
1823+
1824+account_move_reconcile()
1825+
1826+#----------------------------------------------------------
1827+# Tax
1828+#----------------------------------------------------------
1829+"""
1830+a documenter
1831+child_depend: la taxe depend des taxes filles
1832+"""
1833+class account_tax_code(osv.osv):
1834+ """
1835+ A code for the tax object.
1836+
1837+ This code is used for some tax declarations.
1838+ """
1839+ def _sum(self, cr, uid, ids, name, args, context, where ='', where_params=()):
1840+ parent_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)]))
1841+ if context.get('based_on', 'invoices') == 'payments':
1842+ cr.execute('SELECT line.tax_code_id, sum(line.tax_amount) \
1843+ FROM account_move_line AS line, \
1844+ account_move AS move \
1845+ LEFT JOIN account_invoice invoice ON \
1846+ (invoice.move_id = move.id) \
1847+ WHERE line.tax_code_id IN %s '+where+' \
1848+ AND move.id = line.move_id \
1849+ AND ((invoice.state = \'paid\') \
1850+ OR (invoice.id IS NULL)) \
1851+ GROUP BY line.tax_code_id',
1852+ (parent_ids,) + where_params)
1853+ else:
1854+ cr.execute('SELECT line.tax_code_id, sum(line.tax_amount) \
1855+ FROM account_move_line AS line, \
1856+ account_move AS move \
1857+ WHERE line.tax_code_id IN %s '+where+' \
1858+ AND move.id = line.move_id \
1859+ GROUP BY line.tax_code_id',
1860+ (parent_ids,) + where_params)
1861+ res=dict(cr.fetchall())
1862+ obj_precision = self.pool.get('decimal.precision')
1863+ res2 = {}
1864+ for record in self.browse(cr, uid, ids, context=context):
1865+ def _rec_get(record):
1866+ amount = res.get(record.id, 0.0)
1867+ for rec in record.child_ids:
1868+ amount += _rec_get(rec) * rec.sign
1869+ return amount
1870+ res2[record.id] = round(_rec_get(record), obj_precision.precision_get(cr, uid, 'Account'))
1871+ return res2
1872+
1873+ def _sum_year(self, cr, uid, ids, name, args, context=None):
1874+ if context is None:
1875+ context = {}
1876+ move_state = ('posted', )
1877+ if context.get('state', 'all') == 'all':
1878+ move_state = ('draft', 'posted', )
1879+ if context.get('fiscalyear_id', False):
1880+ fiscalyear_id = context['fiscalyear_id']
1881+ else:
1882+ fiscalyear_id = self.pool.get('account.fiscalyear').find(cr, uid, exception=False)
1883+ where = ''
1884+ where_params = ()
1885+ if fiscalyear_id:
1886+ pids = map(lambda x: str(x.id), self.pool.get('account.fiscalyear').browse(cr, uid, fiscalyear_id).period_ids)
1887+ if pids:
1888+ where = ' AND line.period_id IN %s AND move.state IN %s '
1889+ where_params = (tuple(pids), move_state)
1890+ return self._sum(cr, uid, ids, name, args, context,
1891+ where=where, where_params=where_params)
1892+
1893+ def _sum_period(self, cr, uid, ids, name, args, context):
1894+ if context is None:
1895+ context = {}
1896+ move_state = ('posted', )
1897+ if context.get('state', False) == 'all':
1898+ move_state = ('draft', 'posted', )
1899+ if context.get('period_id', False):
1900+ period_id = context['period_id']
1901+ else:
1902+ period_id = self.pool.get('account.period').find(cr, uid)
1903+ if not period_id:
1904+ return dict.fromkeys(ids, 0.0)
1905+ period_id = period_id[0]
1906+ return self._sum(cr, uid, ids, name, args, context,
1907+ where=' AND line.period_id=%s AND move.state IN %s', where_params=(period_id, move_state))
1908+
1909+ _name = 'account.tax.code'
1910+ _description = 'Tax Code'
1911+ _rec_name = 'code'
1912+ _columns = {
1913+ 'name': fields.char('Tax Case Name', size=64, required=True, translate=True),
1914+ 'code': fields.char('Case Code', size=64),
1915+ 'info': fields.text('Description'),
1916+ 'sum': fields.function(_sum_year, string="Year Sum"),
1917+ 'sum_period': fields.function(_sum_period, string="Period Sum"),
1918+ 'parent_id': fields.many2one('account.tax.code', 'Parent Code', select=True),
1919+ 'child_ids': fields.one2many('account.tax.code', 'parent_id', 'Child Codes'),
1920+ 'line_ids': fields.one2many('account.move.line', 'tax_code_id', 'Lines'),
1921+ 'company_id': fields.many2one('res.company', 'Company', required=True),
1922+ '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.'),
1923+ '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"),
1924+ }
1925+
1926+ def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
1927+ if not args:
1928+ args = []
1929+ if context is None:
1930+ context = {}
1931+ ids = self.search(cr, user, ['|',('name',operator,name),('code',operator,name)] + args, limit=limit, context=context)
1932+ return self.name_get(cr, user, ids, context)
1933+
1934+ def name_get(self, cr, uid, ids, context=None):
1935+ if isinstance(ids, (int, long)):
1936+ ids = [ids]
1937+ if not ids:
1938+ return []
1939+ if isinstance(ids, (int, long)):
1940+ ids = [ids]
1941+ reads = self.read(cr, uid, ids, ['name','code'], context, load='_classic_write')
1942+ return [(x['id'], (x['code'] and (x['code'] + ' - ') or '') + x['name']) \
1943+ for x in reads]
1944+
1945+ def _default_company(self, cr, uid, context=None):
1946+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
1947+ if user.company_id:
1948+ return user.company_id.id
1949+ return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
1950+ _defaults = {
1951+ 'company_id': _default_company,
1952+ 'sign': 1.0,
1953+ 'notprintable': False,
1954+ }
1955+
1956+ def copy(self, cr, uid, id, default=None, context=None):
1957+ if default is None:
1958+ default = {}
1959+ default = default.copy()
1960+ default.update({'line_ids': []})
1961+ return super(account_tax_code, self).copy(cr, uid, id, default, context)
1962+
1963+ _check_recursion = check_cycle
1964+ _constraints = [
1965+ (_check_recursion, 'Error ! You can not create recursive accounts.', ['parent_id'])
1966+ ]
1967+ _order = 'code'
1968+
1969+account_tax_code()
1970+
1971+class account_tax(osv.osv):
1972+ """
1973+ A tax object.
1974+
1975+ Type: percent, fixed, none, code
1976+ PERCENT: tax = price * amount
1977+ FIXED: tax = price + amount
1978+ NONE: no tax line
1979+ CODE: execute python code. localcontext = {'price_unit':pu, 'address':address_object}
1980+ return result in the context
1981+ Ex: result=round(price_unit*0.21,4)
1982+ """
1983+
1984+ def get_precision_tax():
1985+ def change_digit_tax(cr):
1986+ res = pooler.get_pool(cr.dbname).get('decimal.precision').precision_get(cr, 1, 'Account')
1987+ return (16, res+2)
1988+ return change_digit_tax
1989+
1990+ _name = 'account.tax'
1991+ _description = 'Tax'
1992+ _columns = {
1993+ 'name': fields.char('Tax Name', size=64, required=True, translate=True, help="This name will be displayed on reports"),
1994+ '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."),
1995+ 'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For taxes of type percentage, enter % ratio between 0-1."),
1996+ 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the tax without removing it."),
1997+ 'type': fields.selection( [('percent','Percentage'), ('fixed','Fixed Amount'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True,
1998+ help="The computation method for the tax amount."),
1999+ 'applicable_type': fields.selection( [('true','Always'), ('code','Given by Python Code')], 'Applicability', required=True,
2000+ help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
2001+ '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."),
2002+ 'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account'),
2003+ 'account_paid_id':fields.many2one('account.account', 'Refund Tax Account'),
2004+ 'parent_id':fields.many2one('account.tax', 'Parent Tax Account', select=True),
2005+ 'child_ids':fields.one2many('account.tax', 'parent_id', 'Child Tax Accounts'),
2006+ '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."),
2007+ 'python_compute':fields.text('Python Code'),
2008+ 'python_compute_inv':fields.text('Python Code (reverse)'),
2009+ 'python_applicable':fields.text('Python Code'),
2010+
2011+ #
2012+ # Fields used for the VAT declaration
2013+ #
2014+ 'base_code_id': fields.many2one('account.tax.code', 'Account Base Code', help="Use this code for the VAT declaration."),
2015+ 'tax_code_id': fields.many2one('account.tax.code', 'Account Tax Code', help="Use this code for the VAT declaration."),
2016+ 'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
2017+ 'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
2018+
2019+ # Same fields for refund invoices
2020+
2021+ 'ref_base_code_id': fields.many2one('account.tax.code', 'Refund Base Code', help="Use this code for the VAT declaration."),
2022+ 'ref_tax_code_id': fields.many2one('account.tax.code', 'Refund Tax Code', help="Use this code for the VAT declaration."),
2023+ 'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
2024+ 'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
2025+ '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"),
2026+ 'company_id': fields.many2one('res.company', 'Company', required=True),
2027+ 'description': fields.char('Tax Code',size=32),
2028+ 'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
2029+ 'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Application', required=True)
2030+
2031+ }
2032+ _sql_constraints = [
2033+ ('name_company_uniq', 'unique(name, company_id)', 'Tax Name must be unique per company!'),
2034+ ]
2035+
2036+ def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
2037+ """
2038+ Returns a list of tupples containing id, name, as internally it is called {def name_get}
2039+ result format: {[(id, name), (id, name), ...]}
2040+
2041+ @param cr: A database cursor
2042+ @param user: ID of the user currently logged in
2043+ @param name: name to search
2044+ @param args: other arguments
2045+ @param operator: default operator is 'ilike', it can be changed
2046+ @param context: context arguments, like lang, time zone
2047+ @param limit: Returns first 'n' ids of complete result, default is 80.
2048+
2049+ @return: Returns a list of tupples containing id and name
2050+ """
2051+ if not args:
2052+ args = []
2053+ if context is None:
2054+ context = {}
2055+ ids = []
2056+ if name:
2057+ ids = self.search(cr, user, [('description', '=', name)] + args, limit=limit, context=context)
2058+ if not ids:
2059+ ids = self.search(cr, user, [('name', operator, name)] + args, limit=limit, context=context)
2060+ else:
2061+ ids = self.search(cr, user, args, limit=limit, context=context or {})
2062+ return self.name_get(cr, user, ids, context=context)
2063+
2064+ def write(self, cr, uid, ids, vals, context=None):
2065+ if vals.get('type', False) and vals['type'] in ('none', 'code'):
2066+ vals.update({'amount': 0.0})
2067+ return super(account_tax, self).write(cr, uid, ids, vals, context=context)
2068+
2069+ def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
2070+ journal_pool = self.pool.get('account.journal')
2071+
2072+ if context and context.has_key('type'):
2073+ if context.get('type') in ('out_invoice','out_refund'):
2074+ args += [('type_tax_use','in',['sale','all'])]
2075+ elif context.get('type') in ('in_invoice','in_refund'):
2076+ args += [('type_tax_use','in',['purchase','all'])]
2077+
2078+ if context and context.has_key('journal_id'):
2079+ journal = journal_pool.browse(cr, uid, context.get('journal_id'))
2080+ if journal.type in ('sale', 'purchase'):
2081+ args += [('type_tax_use','in',[journal.type,'all'])]
2082+
2083+ return super(account_tax, self).search(cr, uid, args, offset, limit, order, context, count)
2084+
2085+ def name_get(self, cr, uid, ids, context=None):
2086+ if not ids:
2087+ return []
2088+ res = []
2089+ for record in self.read(cr, uid, ids, ['description','name'], context=context):
2090+ name = record['description'] and record['description'] or record['name']
2091+ res.append((record['id'],name ))
2092+ return res
2093+
2094+ def _default_company(self, cr, uid, context=None):
2095+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
2096+ if user.company_id:
2097+ return user.company_id.id
2098+ return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
2099+
2100+ _defaults = {
2101+ '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''',
2102+ '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''',
2103+ 'applicable_type': 'true',
2104+ 'type': 'percent',
2105+ 'amount': 0,
2106+ 'price_include': 0,
2107+ 'active': 1,
2108+ 'type_tax_use': 'all',
2109+ 'sequence': 1,
2110+ 'ref_tax_sign': 1,
2111+ 'ref_base_sign': 1,
2112+ 'tax_sign': 1,
2113+ 'base_sign': 1,
2114+ 'include_base_amount': False,
2115+ 'company_id': _default_company,
2116+ }
2117+ _order = 'sequence'
2118+
2119+ def _applicable(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None):
2120+ res = []
2121+ obj_partener_address = self.pool.get('res.partner.address')
2122+ for tax in taxes:
2123+ if tax.applicable_type=='code':
2124+ localdict = {'price_unit':price_unit, 'address':obj_partener_address.browse(cr, uid, address_id), 'product':product, 'partner':partner}
2125+ exec tax.python_applicable in localdict
2126+ if localdict.get('result', False):
2127+ res.append(tax)
2128+ else:
2129+ res.append(tax)
2130+ return res
2131+
2132+ def _unit_compute(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None, quantity=0):
2133+ taxes = self._applicable(cr, uid, taxes, price_unit, address_id, product, partner)
2134+ res = []
2135+ cur_price_unit=price_unit
2136+ obj_partener_address = self.pool.get('res.partner.address')
2137+ for tax in taxes:
2138+ # we compute the amount for the current tax object and append it to the result
2139+ data = {'id':tax.id,
2140+ 'name':tax.description and tax.description + " - " + tax.name or tax.name,
2141+ 'account_collected_id':tax.account_collected_id.id,
2142+ 'account_paid_id':tax.account_paid_id.id,
2143+ 'base_code_id': tax.base_code_id.id,
2144+ 'ref_base_code_id': tax.ref_base_code_id.id,
2145+ 'sequence': tax.sequence,
2146+ 'base_sign': tax.base_sign,
2147+ 'tax_sign': tax.tax_sign,
2148+ 'ref_base_sign': tax.ref_base_sign,
2149+ 'ref_tax_sign': tax.ref_tax_sign,
2150+ 'price_unit': cur_price_unit,
2151+ 'tax_code_id': tax.tax_code_id.id,
2152+ 'ref_tax_code_id': tax.ref_tax_code_id.id,
2153+ }
2154+ res.append(data)
2155+ if tax.type=='percent':
2156+ amount = cur_price_unit * tax.amount
2157+ data['amount'] = amount
2158+
2159+ elif tax.type=='fixed':
2160+ data['amount'] = tax.amount
2161+ data['tax_amount']=quantity
2162+ # data['amount'] = quantity
2163+ elif tax.type=='code':
2164+ address = address_id and obj_partener_address.browse(cr, uid, address_id) or None
2165+ localdict = {'price_unit':cur_price_unit, 'address':address, 'product':product, 'partner':partner}
2166+ exec tax.python_compute in localdict
2167+ amount = localdict['result']
2168+ data['amount'] = amount
2169+ elif tax.type=='balance':
2170+ data['amount'] = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0)
2171+ data['balance'] = cur_price_unit
2172+
2173+ amount2 = data.get('amount', 0.0)
2174+ if tax.child_ids:
2175+ if tax.child_depend:
2176+ latest = res.pop()
2177+ amount = amount2
2178+ child_tax = self._unit_compute(cr, uid, tax.child_ids, amount, address_id, product, partner, quantity)
2179+ res.extend(child_tax)
2180+ if tax.child_depend:
2181+ for r in res:
2182+ for name in ('base','ref_base'):
2183+ if latest[name+'_code_id'] and latest[name+'_sign'] and not r[name+'_code_id']:
2184+ r[name+'_code_id'] = latest[name+'_code_id']
2185+ r[name+'_sign'] = latest[name+'_sign']
2186+ r['price_unit'] = latest['price_unit']
2187+ latest[name+'_code_id'] = False
2188+ for name in ('tax','ref_tax'):
2189+ if latest[name+'_code_id'] and latest[name+'_sign'] and not r[name+'_code_id']:
2190+ r[name+'_code_id'] = latest[name+'_code_id']
2191+ r[name+'_sign'] = latest[name+'_sign']
2192+ r['amount'] = data['amount']
2193+ latest[name+'_code_id'] = False
2194+ if tax.include_base_amount:
2195+ cur_price_unit+=amount2
2196+ return res
2197+
2198+ def compute_all(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
2199+ """
2200+ RETURN: {
2201+ 'total': 0.0, # Total without taxes
2202+ 'total_included: 0.0, # Total with taxes
2203+ 'taxes': [] # List of taxes, see compute for the format
2204+ }
2205+ """
2206+ precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
2207+ totalin = totalex = round(price_unit * quantity, precision)
2208+ tin = []
2209+ tex = []
2210+ for tax in taxes:
2211+ if tax.price_include:
2212+ tin.append(tax)
2213+ else:
2214+ tex.append(tax)
2215+ tin = self.compute_inv(cr, uid, tin, price_unit, quantity, address_id=address_id, product=product, partner=partner)
2216+ for r in tin:
2217+ totalex -= r.get('amount', 0.0)
2218+ totlex_qty = 0.0
2219+ try:
2220+ totlex_qty = totalex/quantity
2221+ except:
2222+ pass
2223+ tex = self._compute(cr, uid, tex, totlex_qty, quantity, address_id=address_id, product=product, partner=partner)
2224+ for r in tex:
2225+ totalin += r.get('amount', 0.0)
2226+ return {
2227+ 'total': totalex,
2228+ 'total_included': totalin,
2229+ 'taxes': tin + tex
2230+ }
2231+
2232+ def compute(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
2233+ logger = netsvc.Logger()
2234+ logger.notifyChannel("warning", netsvc.LOG_WARNING,
2235+ "Deprecated, use compute_all(...)['taxes'] instead of compute(...) to manage prices with tax included")
2236+ return self._compute(cr, uid, taxes, price_unit, quantity, address_id, product, partner)
2237+
2238+ def _compute(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
2239+ """
2240+ Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
2241+
2242+ RETURN:
2243+ [ tax ]
2244+ tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
2245+ one tax for each tax id in IDS and their children
2246+ """
2247+ res = self._unit_compute(cr, uid, taxes, price_unit, address_id, product, partner, quantity)
2248+ total = 0.0
2249+ precision_pool = self.pool.get('decimal.precision')
2250+ for r in res:
2251+ if r.get('balance',False):
2252+ r['amount'] = round(r.get('balance', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account')) - total
2253+ else:
2254+ r['amount'] = round(r.get('amount', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account'))
2255+ total += r['amount']
2256+ return res
2257+
2258+ def _unit_compute_inv(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None):
2259+ taxes = self._applicable(cr, uid, taxes, price_unit, address_id, product, partner)
2260+ obj_partener_address = self.pool.get('res.partner.address')
2261+ res = []
2262+ taxes.reverse()
2263+ cur_price_unit = price_unit
2264+
2265+ tax_parent_tot = 0.0
2266+ for tax in taxes:
2267+ if (tax.type=='percent') and not tax.include_base_amount:
2268+ tax_parent_tot += tax.amount
2269+
2270+ for tax in taxes:
2271+ if (tax.type=='fixed') and not tax.include_base_amount:
2272+ cur_price_unit -= tax.amount
2273+
2274+ for tax in taxes:
2275+ if tax.type=='percent':
2276+ if tax.include_base_amount:
2277+ amount = cur_price_unit - (cur_price_unit / (1 + tax.amount))
2278+ else:
2279+ amount = (cur_price_unit / (1 + tax_parent_tot)) * tax.amount
2280+
2281+ elif tax.type=='fixed':
2282+ amount = tax.amount
2283+
2284+ elif tax.type=='code':
2285+ address = address_id and obj_partener_address.browse(cr, uid, address_id) or None
2286+ localdict = {'price_unit':cur_price_unit, 'address':address, 'product':product, 'partner':partner}
2287+ exec tax.python_compute_inv in localdict
2288+ amount = localdict['result']
2289+ elif tax.type=='balance':
2290+ amount = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0)
2291+
2292+ if tax.include_base_amount:
2293+ cur_price_unit -= amount
2294+ todo = 0
2295+ else:
2296+ todo = 1
2297+ res.append({
2298+ 'id': tax.id,
2299+ 'todo': todo,
2300+ 'name': tax.name,
2301+ 'amount': amount,
2302+ 'account_collected_id': tax.account_collected_id.id,
2303+ 'account_paid_id': tax.account_paid_id.id,
2304+ 'base_code_id': tax.base_code_id.id,
2305+ 'ref_base_code_id': tax.ref_base_code_id.id,
2306+ 'sequence': tax.sequence,
2307+ 'base_sign': tax.base_sign,
2308+ 'tax_sign': tax.tax_sign,
2309+ 'ref_base_sign': tax.ref_base_sign,
2310+ 'ref_tax_sign': tax.ref_tax_sign,
2311+ 'price_unit': cur_price_unit,
2312+ 'tax_code_id': tax.tax_code_id.id,
2313+ 'ref_tax_code_id': tax.ref_tax_code_id.id,
2314+ })
2315+ if tax.child_ids:
2316+ if tax.child_depend:
2317+ del res[-1]
2318+ amount = price_unit
2319+
2320+ parent_tax = self._unit_compute_inv(cr, uid, tax.child_ids, amount, address_id, product, partner)
2321+ res.extend(parent_tax)
2322+
2323+ total = 0.0
2324+ for r in res:
2325+ if r['todo']:
2326+ total += r['amount']
2327+ for r in res:
2328+ r['price_unit'] -= total
2329+ r['todo'] = 0
2330+ return res
2331+
2332+ def compute_inv(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
2333+ """
2334+ Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
2335+ Price Unit is a VAT included price
2336+
2337+ RETURN:
2338+ [ tax ]
2339+ tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
2340+ one tax for each tax id in IDS and their children
2341+ """
2342+ res = self._unit_compute_inv(cr, uid, taxes, price_unit, address_id, product, partner=None)
2343+ total = 0.0
2344+ obj_precision = self.pool.get('decimal.precision')
2345+ for r in res:
2346+ prec = obj_precision.precision_get(cr, uid, 'Account')
2347+ if r.get('balance',False):
2348+ r['amount'] = round(r['balance'] * quantity, prec) - total
2349+ else:
2350+ r['amount'] = round(r['amount'] * quantity, prec)
2351+ total += r['amount']
2352+ return res
2353+
2354+account_tax()
2355+
2356+# ---------------------------------------------------------
2357+# Account Entries Models
2358+# ---------------------------------------------------------
2359+
2360+class account_model(osv.osv):
2361+ _name = "account.model"
2362+ _description = "Account Model"
2363+ _columns = {
2364+ 'name': fields.char('Model Name', size=64, required=True, help="This is a model for recurring accounting entries"),
2365+ 'journal_id': fields.many2one('account.journal', 'Journal', required=True),
2366+ 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
2367+ 'lines_id': fields.one2many('account.model.line', 'model_id', 'Model Entries'),
2368+ 'legend': fields.text('Legend', readonly=True, size=100),
2369+ }
2370+
2371+ _defaults = {
2372+ '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'),
2373+ }
2374+ def generate(self, cr, uid, ids, datas={}, context=None):
2375+ move_ids = []
2376+ entry = {}
2377+ account_move_obj = self.pool.get('account.move')
2378+ account_move_line_obj = self.pool.get('account.move.line')
2379+ pt_obj = self.pool.get('account.payment.term')
2380+
2381+ if context is None:
2382+ context = {}
2383+
2384+ if datas.get('date', False):
2385+ context.update({'date': datas['date']})
2386+
2387+ period_id = self.pool.get('account.period').find(cr, uid, dt=context.get('date', False))
2388+ if not period_id:
2389+ raise osv.except_osv(_('No period found !'), _('Unable to find a valid period !'))
2390+ period_id = period_id[0]
2391+
2392+ for model in self.browse(cr, uid, ids, context=context):
2393+ try:
2394+ entry['name'] = model.name%{'year':time.strftime('%Y'), 'month':time.strftime('%m'), 'date':time.strftime('%Y-%m')}
2395+ except:
2396+ raise osv.except_osv(_('Wrong model !'), _('You have a wrong expression "%(...)s" in your model !'))
2397+
2398+ move_id = account_move_obj.create(cr, uid, {
2399+ 'ref': entry['name'],
2400+ 'period_id': period_id,
2401+ 'journal_id': model.journal_id.id,
2402+ 'date': context.get('date',time.strftime('%Y-%m-%d'))
2403+ })
2404+ move_ids.append(move_id)
2405+ for line in model.lines_id:
2406+ analytic_account_id = False
2407+ if line.analytic_account_id:
2408+ if not model.journal_id.analytic_journal_id:
2409+ raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (model.journal_id.name,))
2410+ analytic_account_id = line.analytic_account_id.id
2411+ val = {
2412+ 'move_id': move_id,
2413+ 'journal_id': model.journal_id.id,
2414+ 'period_id': period_id,
2415+ 'analytic_account_id': analytic_account_id
2416+ }
2417+
2418+ date_maturity = time.strftime('%Y-%m-%d')
2419+ if line.date_maturity == 'partner':
2420+ if not line.partner_id:
2421+ raise osv.except_osv(_('Error !'), _("Maturity date of entry line generated by model line '%s' of model '%s' is based on partner payment term!" \
2422+ "\nPlease define partner on it!")%(line.name, model.name))
2423+ if line.partner_id.property_payment_term:
2424+ payment_term_id = line.partner_id.property_payment_term.id
2425+ pterm_list = pt_obj.compute(cr, uid, payment_term_id, value=1, date_ref=date_maturity)
2426+ if pterm_list:
2427+ pterm_list = [l[0] for l in pterm_list]
2428+ pterm_list.sort()
2429+ date_maturity = pterm_list[-1]
2430+
2431+ val.update({
2432+ 'name': line.name,
2433+ 'quantity': line.quantity,
2434+ 'debit': line.debit,
2435+ 'credit': line.credit,
2436+ 'account_id': line.account_id.id,
2437+ 'move_id': move_id,
2438+ 'partner_id': line.partner_id.id,
2439+ 'date': context.get('date',time.strftime('%Y-%m-%d')),
2440+ 'date_maturity': date_maturity
2441+ })
2442+ c = context.copy()
2443+ c.update({'journal_id': model.journal_id.id,'period_id': period_id})
2444+ account_move_line_obj.create(cr, uid, val, context=c)
2445+
2446+ return move_ids
2447+
2448+account_model()
2449+
2450+class account_model_line(osv.osv):
2451+ _name = "account.model.line"
2452+ _description = "Account Model Entries"
2453+ _columns = {
2454+ 'name': fields.char('Name', size=64, required=True),
2455+ 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the resources from lower sequences to higher ones."),
2456+ 'quantity': fields.float('Quantity', digits_compute=dp.get_precision('Account'), help="The optional quantity on entries."),
2457+ 'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')),
2458+ 'credit': fields.float('Credit', digits_compute=dp.get_precision('Account')),
2459+ 'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade"),
2460+ 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', ondelete="cascade"),
2461+ 'model_id': fields.many2one('account.model', 'Model', required=True, ondelete="cascade", select=True),
2462+ 'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency."),
2463+ 'currency_id': fields.many2one('res.currency', 'Currency'),
2464+ 'partner_id': fields.many2one('res.partner', 'Partner'),
2465+ '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."),
2466+ }
2467+ _order = 'sequence'
2468+ _sql_constraints = [
2469+ ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in model, they must be positive!'),
2470+ ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in model, they must be positive!'),
2471+ ]
2472+account_model_line()
2473+
2474+# ---------------------------------------------------------
2475+# Account Subscription
2476+# ---------------------------------------------------------
2477+
2478+
2479+class account_subscription(osv.osv):
2480+ _name = "account.subscription"
2481+ _description = "Account Subscription"
2482+ _columns = {
2483+ 'name': fields.char('Name', size=64, required=True),
2484+ 'ref': fields.char('Reference', size=16),
2485+ 'model_id': fields.many2one('account.model', 'Model', required=True),
2486+ 'date_start': fields.date('Start Date', required=True),
2487+ 'period_total': fields.integer('Number of Periods', required=True),
2488+ 'period_nbr': fields.integer('Period', required=True),
2489+ 'period_type': fields.selection([('day','days'),('month','month'),('year','year')], 'Period Type', required=True),
2490+ 'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'State', required=True, readonly=True),
2491+ 'lines_id': fields.one2many('account.subscription.line', 'subscription_id', 'Subscription Lines')
2492+ }
2493+ _defaults = {
2494+ 'date_start': lambda *a: time.strftime('%Y-%m-%d'),
2495+ 'period_type': 'month',
2496+ 'period_total': 12,
2497+ 'period_nbr': 1,
2498+ 'state': 'draft',
2499+ }
2500+ def state_draft(self, cr, uid, ids, context=None):
2501+ self.write(cr, uid, ids, {'state':'draft'})
2502+ return False
2503+
2504+ def check(self, cr, uid, ids, context=None):
2505+ todone = []
2506+ for sub in self.browse(cr, uid, ids, context=context):
2507+ ok = True
2508+ for line in sub.lines_id:
2509+ if not line.move_id.id:
2510+ ok = False
2511+ break
2512+ if ok:
2513+ todone.append(sub.id)
2514+ if todone:
2515+ self.write(cr, uid, todone, {'state':'done'})
2516+ return False
2517+
2518+ def remove_line(self, cr, uid, ids, context=None):
2519+ toremove = []
2520+ for sub in self.browse(cr, uid, ids, context=context):
2521+ for line in sub.lines_id:
2522+ if not line.move_id.id:
2523+ toremove.append(line.id)
2524+ if toremove:
2525+ self.pool.get('account.subscription.line').unlink(cr, uid, toremove)
2526+ self.write(cr, uid, ids, {'state':'draft'})
2527+ return False
2528+
2529+ def compute(self, cr, uid, ids, context=None):
2530+ for sub in self.browse(cr, uid, ids, context=context):
2531+ ds = sub.date_start
2532+ for i in range(sub.period_total):
2533+ self.pool.get('account.subscription.line').create(cr, uid, {
2534+ 'date': ds,
2535+ 'subscription_id': sub.id,
2536+ })
2537+ if sub.period_type=='day':
2538+ ds = (datetime.strptime(ds, '%Y-%m-%d') + relativedelta(days=sub.period_nbr)).strftime('%Y-%m-%d')
2539+ if sub.period_type=='month':
2540+ ds = (datetime.strptime(ds, '%Y-%m-%d') + relativedelta(months=sub.period_nbr)).strftime('%Y-%m-%d')
2541+ if sub.period_type=='year':
2542+ ds = (datetime.strptime(ds, '%Y-%m-%d') + relativedelta(years=sub.period_nbr)).strftime('%Y-%m-%d')
2543+ self.write(cr, uid, ids, {'state':'running'})
2544+ return True
2545+
2546+account_subscription()
2547+
2548+class account_subscription_line(osv.osv):
2549+ _name = "account.subscription.line"
2550+ _description = "Account Subscription Line"
2551+ _columns = {
2552+ 'subscription_id': fields.many2one('account.subscription', 'Subscription', required=True, select=True),
2553+ 'date': fields.date('Date', required=True),
2554+ 'move_id': fields.many2one('account.move', 'Entry'),
2555+ }
2556+
2557+ def move_create(self, cr, uid, ids, context=None):
2558+ tocheck = {}
2559+ all_moves = []
2560+ obj_model = self.pool.get('account.model')
2561+ for line in self.browse(cr, uid, ids, context=context):
2562+ datas = {
2563+ 'date': line.date,
2564+ }
2565+ move_ids = obj_model.generate(cr, uid, [line.subscription_id.model_id.id], datas, context)
2566+ tocheck[line.subscription_id.id] = True
2567+ self.write(cr, uid, [line.id], {'move_id':move_ids[0]})
2568+ all_moves.extend(move_ids)
2569+ if tocheck:
2570+ self.pool.get('account.subscription').check(cr, uid, tocheck.keys(), context)
2571+ return all_moves
2572+
2573+ _rec_name = 'date'
2574+
2575+account_subscription_line()
2576+
2577+# ---------------------------------------------------------------
2578+# Account Templates: Account, Tax, Tax Code and chart. + Wizard
2579+# ---------------------------------------------------------------
2580+
2581+class account_tax_template(osv.osv):
2582+ _name = 'account.tax.template'
2583+account_tax_template()
2584+
2585+class account_account_template(osv.osv):
2586+ _order = "code"
2587+ _name = "account.account.template"
2588+ _description ='Templates for Accounts'
2589+
2590+ _columns = {
2591+ 'name': fields.char('Name', size=128, required=True, select=True),
2592+ 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
2593+ 'code': fields.char('Code', size=64, select=1),
2594+ 'type': fields.selection([
2595+ ('receivable','Receivable'),
2596+ ('payable','Payable'),
2597+ ('view','View'),
2598+ ('consolidation','Consolidation'),
2599+ ('liquidity','Liquidity'),
2600+ ('other','Regular'),
2601+ ('closed','Closed'),
2602+ ], 'Internal Type', required=True,help="This type is used to differentiate types with "\
2603+ "special effects in OpenERP: view can not have entries, consolidation are accounts that "\
2604+ "can have children accounts for multi-company consolidations, payable/receivable are for "\
2605+ "partners accounts (for debit/credit computations), closed for depreciated accounts."),
2606+ 'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
2607+ help="These types are defined according to your country. The type contains more information "\
2608+ "about the account and its specificities."),
2609+ 'reconcile': fields.boolean('Allow Reconciliation', help="Check this option if you want the user to reconcile entries in this account."),
2610+ 'shortcut': fields.char('Shortcut', size=12),
2611+ 'note': fields.text('Note'),
2612+ 'parent_id': fields.many2one('account.account.template', 'Parent Account Template', ondelete='cascade'),
2613+ 'child_parent_ids':fields.one2many('account.account.template', 'parent_id', 'Children'),
2614+ 'tax_ids': fields.many2many('account.tax.template', 'account_account_template_tax_rel', 'account_id', 'tax_id', 'Default Taxes'),
2615+ 'nocreate': fields.boolean('Optional create', help="If checked, the new chart of accounts will not contain this by default."),
2616+ }
2617+
2618+ _defaults = {
2619+ 'reconcile': False,
2620+ 'type': 'view',
2621+ 'nocreate': False,
2622+ }
2623+
2624+ def _check_type(self, cr, uid, ids, context=None):
2625+ if context is None:
2626+ context = {}
2627+ accounts = self.browse(cr, uid, ids, context=context)
2628+ for account in accounts:
2629+ if account.parent_id and account.parent_id.type != 'view':
2630+ return False
2631+ return True
2632+
2633+ _check_recursion = check_cycle
2634+ _constraints = [
2635+ (_check_recursion, 'Error ! You can not create recursive account templates.', ['parent_id']),
2636+ (_check_type, 'Configuration Error!\nYou can not define children to an account with internal type different of "View"! ', ['type']),
2637+
2638+ ]
2639+
2640+ def name_get(self, cr, uid, ids, context=None):
2641+ if not ids:
2642+ return []
2643+ reads = self.read(cr, uid, ids, ['name','code'], context=context)
2644+ res = []
2645+ for record in reads:
2646+ name = record['name']
2647+ if record['code']:
2648+ name = record['code']+' '+name
2649+ res.append((record['id'],name ))
2650+ return res
2651+
2652+account_account_template()
2653+
2654+class account_add_tmpl_wizard(osv.osv_memory):
2655+ """Add one more account from the template.
2656+
2657+ With the 'nocreate' option, some accounts may not be created. Use this to add them later."""
2658+ _name = 'account.addtmpl.wizard'
2659+
2660+ def _get_def_cparent(self, cr, uid, context=None):
2661+ acc_obj = self.pool.get('account.account')
2662+ tmpl_obj = self.pool.get('account.account.template')
2663+ tids = tmpl_obj.read(cr, uid, [context['tmpl_ids']], ['parent_id'])
2664+ if not tids or not tids[0]['parent_id']:
2665+ return False
2666+ ptids = tmpl_obj.read(cr, uid, [tids[0]['parent_id'][0]], ['code'])
2667+ res = None
2668+ if not ptids or not ptids[0]['code']:
2669+ raise osv.except_osv(_('Error !'), _('I can not locate a parent code for the template account!'))
2670+ res = acc_obj.search(cr, uid, [('code','=',ptids[0]['code'])])
2671+ return res and res[0] or False
2672+
2673+ _columns = {
2674+ 'cparent_id':fields.many2one('account.account', 'Parent target', help="Creates an account with the selected template under this existing parent.", required=True),
2675+ }
2676+ _defaults = {
2677+ 'cparent_id': _get_def_cparent,
2678+ }
2679+
2680+ def action_create(self,cr,uid,ids,context=None):
2681+ if context is None:
2682+ context = {}
2683+ acc_obj = self.pool.get('account.account')
2684+ tmpl_obj = self.pool.get('account.account.template')
2685+ data = self.read(cr, uid, ids)
2686+ company_id = acc_obj.read(cr, uid, [data[0]['cparent_id']], ['company_id'])[0]['company_id'][0]
2687+ account_template = tmpl_obj.browse(cr, uid, context['tmpl_ids'])
2688+ vals = {
2689+ 'name': account_template.name,
2690+ 'currency_id': account_template.currency_id and account_template.currency_id.id or False,
2691+ 'code': account_template.code,
2692+ 'type': account_template.type,
2693+ 'user_type': account_template.user_type and account_template.user_type.id or False,
2694+ 'reconcile': account_template.reconcile,
2695+ 'shortcut': account_template.shortcut,
2696+ 'note': account_template.note,
2697+ 'parent_id': data[0]['cparent_id'],
2698+ 'company_id': company_id,
2699+ }
2700+ acc_obj.create(cr, uid, vals)
2701+ return {'type':'state', 'state': 'end' }
2702+
2703+ def action_cancel(self, cr, uid, ids, context=None):
2704+ return { 'type': 'state', 'state': 'end' }
2705+
2706+account_add_tmpl_wizard()
2707+
2708+class account_tax_code_template(osv.osv):
2709+
2710+ _name = 'account.tax.code.template'
2711+ _description = 'Tax Code Template'
2712+ _order = 'code'
2713+ _rec_name = 'code'
2714+ _columns = {
2715+ 'name': fields.char('Tax Case Name', size=64, required=True),
2716+ 'code': fields.char('Case Code', size=64),
2717+ 'info': fields.text('Description'),
2718+ 'parent_id': fields.many2one('account.tax.code.template', 'Parent Code', select=True),
2719+ 'child_ids': fields.one2many('account.tax.code.template', 'parent_id', 'Child Codes'),
2720+ 'sign': fields.float('Sign For Parent', required=True),
2721+ '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"),
2722+ }
2723+
2724+ _defaults = {
2725+ 'sign': 1.0,
2726+ 'notprintable': False,
2727+ }
2728+
2729+ def name_get(self, cr, uid, ids, context=None):
2730+ if not ids:
2731+ return []
2732+ if isinstance(ids, (int, long)):
2733+ ids = [ids]
2734+ reads = self.read(cr, uid, ids, ['name','code'], context, load='_classic_write')
2735+ return [(x['id'], (x['code'] and x['code'] + ' - ' or '') + x['name']) \
2736+ for x in reads]
2737+
2738+ _check_recursion = check_cycle
2739+ _constraints = [
2740+ (_check_recursion, 'Error ! You can not create recursive Tax Codes.', ['parent_id'])
2741+ ]
2742+ _order = 'code,name'
2743+account_tax_code_template()
2744+
2745+
2746+class account_chart_template(osv.osv):
2747+ _name="account.chart.template"
2748+ _description= "Templates for Account Chart"
2749+
2750+ _columns={
2751+ 'name': fields.char('Name', size=64, required=True),
2752+ 'account_root_id': fields.many2one('account.account.template','Root Account',required=True,domain=[('parent_id','=',False)]),
2753+ 'tax_code_root_id': fields.many2one('account.tax.code.template','Root Tax Code',required=True,domain=[('parent_id','=',False)]),
2754+ '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'),
2755+ 'bank_account_view_id': fields.many2one('account.account.template','Bank Account',required=True),
2756+ 'property_account_receivable': fields.many2one('account.account.template','Receivable Account'),
2757+ 'property_account_payable': fields.many2one('account.account.template','Payable Account'),
2758+ 'property_account_expense_categ': fields.many2one('account.account.template','Expense Category Account'),
2759+ 'property_account_income_categ': fields.many2one('account.account.template','Income Category Account'),
2760+ 'property_account_expense': fields.many2one('account.account.template','Expense Account on Product Template'),
2761+ 'property_account_income': fields.many2one('account.account.template','Income Account on Product Template'),
2762+ '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'),
2763+ 'property_account_income_opening': fields.many2one('account.account.template','Opening Entries Income Account'),
2764+ 'property_account_expense_opening': fields.many2one('account.account.template','Opening Entries Expense Account'),
2765+ }
2766+
2767+account_chart_template()
2768+
2769+class account_tax_template(osv.osv):
2770+
2771+ _name = 'account.tax.template'
2772+ _description = 'Templates for Taxes'
2773+
2774+ _columns = {
2775+ 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
2776+ 'name': fields.char('Tax Name', size=64, required=True),
2777+ '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."),
2778+ 'amount': fields.float('Amount', required=True, digits=(14,4), help="For Tax Type percent enter % ratio between 0-1."),
2779+ 'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True),
2780+ '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."),
2781+ '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."),
2782+ 'account_collected_id':fields.many2one('account.account.template', 'Invoice Tax Account'),
2783+ 'account_paid_id':fields.many2one('account.account.template', 'Refund Tax Account'),
2784+ 'parent_id':fields.many2one('account.tax.template', 'Parent Tax Account', select=True),
2785+ '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."),
2786+ 'python_compute':fields.text('Python Code'),
2787+ 'python_compute_inv':fields.text('Python Code (reverse)'),
2788+ 'python_applicable':fields.text('Python Code'),
2789+
2790+ #
2791+ # Fields used for the VAT declaration
2792+ #
2793+ 'base_code_id': fields.many2one('account.tax.code.template', 'Base Code', help="Use this code for the VAT declaration."),
2794+ 'tax_code_id': fields.many2one('account.tax.code.template', 'Tax Code', help="Use this code for the VAT declaration."),
2795+ 'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
2796+ 'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
2797+
2798+ # Same fields for refund invoices
2799+
2800+ 'ref_base_code_id': fields.many2one('account.tax.code.template', 'Refund Base Code', help="Use this code for the VAT declaration."),
2801+ 'ref_tax_code_id': fields.many2one('account.tax.code.template', 'Refund Tax Code', help="Use this code for the VAT declaration."),
2802+ 'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
2803+ 'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
2804+ '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."),
2805+ 'description': fields.char('Internal Name', size=32),
2806+ 'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Use In', required=True,),
2807+ 'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
2808+ }
2809+
2810+ def name_get(self, cr, uid, ids, context=None):
2811+ if not ids:
2812+ return []
2813+ res = []
2814+ for record in self.read(cr, uid, ids, ['description','name'], context=context):
2815+ name = record['description'] and record['description'] or record['name']
2816+ res.append((record['id'],name ))
2817+ return res
2818+
2819+ def _default_company(self, cr, uid, context=None):
2820+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
2821+ if user.company_id:
2822+ return user.company_id.id
2823+ return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
2824+
2825+ _defaults = {
2826+ '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''',
2827+ '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''',
2828+ 'applicable_type': 'true',
2829+ 'type': 'percent',
2830+ 'amount': 0,
2831+ 'sequence': 1,
2832+ 'ref_tax_sign': 1,
2833+ 'ref_base_sign': 1,
2834+ 'tax_sign': 1,
2835+ 'base_sign': 1,
2836+ 'include_base_amount': False,
2837+ 'type_tax_use': 'all',
2838+ 'price_include': 0,
2839+ }
2840+ _order = 'sequence'
2841+
2842+account_tax_template()
2843+
2844+# Fiscal Position Templates
2845+
2846+class account_fiscal_position_template(osv.osv):
2847+ _name = 'account.fiscal.position.template'
2848+ _description = 'Template for Fiscal Position'
2849+
2850+ _columns = {
2851+ 'name': fields.char('Fiscal Position Template', size=64, required=True),
2852+ 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
2853+ 'account_ids': fields.one2many('account.fiscal.position.account.template', 'position_id', 'Account Mapping'),
2854+ 'tax_ids': fields.one2many('account.fiscal.position.tax.template', 'position_id', 'Tax Mapping')
2855+ }
2856+
2857+account_fiscal_position_template()
2858+
2859+class account_fiscal_position_tax_template(osv.osv):
2860+ _name = 'account.fiscal.position.tax.template'
2861+ _description = 'Template Tax Fiscal Position'
2862+ _rec_name = 'position_id'
2863+
2864+ _columns = {
2865+ 'position_id': fields.many2one('account.fiscal.position.template', 'Fiscal Position', required=True, ondelete='cascade'),
2866+ 'tax_src_id': fields.many2one('account.tax.template', 'Tax Source', required=True),
2867+ 'tax_dest_id': fields.many2one('account.tax.template', 'Replacement Tax')
2868+ }
2869+
2870+account_fiscal_position_tax_template()
2871+
2872+class account_fiscal_position_account_template(osv.osv):
2873+ _name = 'account.fiscal.position.account.template'
2874+ _description = 'Template Account Fiscal Mapping'
2875+ _rec_name = 'position_id'
2876+ _columns = {
2877+ 'position_id': fields.many2one('account.fiscal.position.template', 'Fiscal Mapping', required=True, ondelete='cascade'),
2878+ 'account_src_id': fields.many2one('account.account.template', 'Account Source', domain=[('type','<>','view')], required=True),
2879+ 'account_dest_id': fields.many2one('account.account.template', 'Account Destination', domain=[('type','<>','view')], required=True)
2880+ }
2881+
2882+account_fiscal_position_account_template()
2883+
2884+# ---------------------------------------------------------
2885+# Account Financial Report
2886+# ---------------------------------------------------------
2887+
2888+class account_financial_report(osv.osv):
2889+ _name = "account.financial.report"
2890+ _description = "Account Report"
2891+
2892+ def _get_level(self, cr, uid, ids, field_name, arg, context=None):
2893+ res = {}
2894+ for report in self.browse(cr, uid, ids, context=context):
2895+ level = 0
2896+ if report.parent_id:
2897+ level = report.parent_id.level + 1
2898+ res[report.id] = level
2899+ return res
2900+
2901+ def _get_children_by_order(self, cr, uid, ids, context=None):
2902+ res = []
2903+ for id in ids:
2904+ res.append(id)
2905+ ids2 = self.search(cr, uid, [('parent_id', '=', id)], order='sequence ASC', context=context)
2906+ res += self._get_children_by_order(cr, uid, ids2, context=context)
2907+ return res
2908+
2909+ def _get_balance(self, cr, uid, ids, name, args, context=None):
2910+ res = {}
2911+ res_all = {}
2912+ for report in self.browse(cr, uid, ids, context=context):
2913+ balance = 0.0
2914+ if report.id in res_all:
2915+ balance = res_all[report.id]
2916+ elif report.type == 'accounts':
2917+ # it's the sum of balance of the linked accounts
2918+ for a in report.account_ids:
2919+ balance += a.balance
2920+ elif report.type == 'account_report' and report.account_report_id:
2921+ # it's the amount of the linked report
2922+ res2 = self._get_balance(cr, uid, [report.account_report_id.id], 'balance', False, context=context)
2923+ res_all.update(res2)
2924+ for key, value in res2.items():
2925+ balance += value
2926+ elif report.type == 'sum':
2927+ # it's the sum of balance of the children of this account.report
2928+ #for child in report.children_ids:
2929+ res2 = self._get_balance(cr, uid, [rec.id for rec in report.children_ids], 'balance', False, context=context)
2930+ res_all.update(res2)
2931+ for key, value in res2.items():
2932+ balance += value
2933+ res[report.id] = balance
2934+ res_all[report.id] = balance
2935+ return res
2936+
2937+ _columns = {
2938+ 'name': fields.char('Report Name', size=128, required=True),
2939+ 'parent_id': fields.many2one('account.financial.report', 'Parent'),
2940+ 'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'),
2941+ 'sequence': fields.integer('Sequence'),
2942+ 'note': fields.text('Notes'),
2943+ 'balance': fields.function(_get_balance, 'Balance'),
2944+ 'level': fields.function(_get_level, string='Level', store=True, type='integer'),
2945+ 'type': fields.selection([
2946+ ('sum','View'),
2947+ ('accounts','Accounts'),
2948+ ('account_type','Account Type'),
2949+ ('account_report','Report Value'),
2950+ ],'Type'),
2951+ 'account_ids': fields.many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts'),
2952+ 'display_detail': fields.boolean('Display details', help='Display every account with its balance instead of the sum.'),
2953+ 'account_report_id': fields.many2one('account.financial.report', 'Report Value'),
2954+ 'account_type_ids': fields.many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types'),
2955+ }
2956+
2957+ _defaults = {
2958+ 'type': 'sum',
2959+ }
2960+
2961+account_financial_report()
2962+
2963+# ---------------------------------------------------------
2964+# Account generation from template wizards
2965+# ---------------------------------------------------------
2966+
2967+class wizard_multi_charts_accounts(osv.osv_memory):
2968+ """
2969+ Create a new account chart for a company.
2970+ Wizards ask for:
2971+ * a company
2972+ * an account chart template
2973+ * a number of digits for formatting code of non-view accounts
2974+ * a list of bank accounts owned by the company
2975+ Then, the wizard:
2976+ * generates all accounts from the template and assigns them to the right company
2977+ * generates all taxes and tax codes, changing account assignations
2978+ * generates all accounting properties and assigns them correctly
2979+ """
2980+ _name='wizard.multi.charts.accounts'
2981+ _inherit = 'res.config'
2982+
2983+ _columns = {
2984+ 'company_id':fields.many2one('res.company', 'Company', required=True),
2985+ 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
2986+ 'bank_accounts_id': fields.one2many('account.bank.accounts.wizard', 'bank_account_id', 'Cash and Banks', required=True),
2987+ 'code_digits':fields.integer('# of Digits', required=True, help="No. of Digits to use for account code"),
2988+ '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."),
2989+ "sale_tax": fields.many2one("account.tax.template", "Default Sale Tax"),
2990+ "purchase_tax": fields.many2one("account.tax.template", "Default Purchase Tax"),
2991+ }
2992+ def onchange_chart_template_id(self, cr, uid, ids, chart_template_id=False, context=None):
2993+ res = {}
2994+ res['value'] = {}
2995+ res['value']["sale_tax"] = False
2996+ res['value']["purchase_tax"] = False
2997+ if chart_template_id:
2998+ # 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
2999+ sale_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
3000+ , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all'))], order="sequence, id desc")
3001+ purchase_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
3002+ , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all'))], order="sequence, id desc")
3003+
3004+ res['value']["sale_tax"] = sale_tax_ids and sale_tax_ids[0] or False
3005+ res['value']["purchase_tax"] = purchase_tax_ids and purchase_tax_ids[0] or False
3006+ return res
3007+
3008+ def _get_purchase_tax(self, cr, uid, context=None):
3009+ ids = self.pool.get('account.chart.template').search(cr, uid, [], context=context)
3010+ if ids:
3011+ chart_template_id = ids[0]
3012+ purchase_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
3013+ , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all'))], order="sequence")
3014+ return purchase_tax_ids and purchase_tax_ids[0] or False
3015+ return False
3016+
3017+ def _get_sale_tax(self, cr, uid, context=None):
3018+ ids = self.pool.get('account.chart.template').search(cr, uid, [], context=context)
3019+ if ids:
3020+ chart_template_id = ids[0]
3021+ sale_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
3022+ , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all'))], order="sequence")
3023+ return sale_tax_ids and sale_tax_ids[0] or False
3024+ return False
3025+
3026+ def _get_chart(self, cr, uid, context=None):
3027+ ids = self.pool.get('account.chart.template').search(cr, uid, [], context=context)
3028+ if ids:
3029+ return ids[0]
3030+ return False
3031+
3032+ def _get_default_accounts(self, cr, uid, context=None):
3033+ return [
3034+ {'acc_name': _('Cash'),'account_type':'cash'}
3035+ ]
3036+
3037+ _defaults = {
3038+ 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, [uid], c)[0].company_id.id,
3039+ 'chart_template_id': _get_chart,
3040+ 'bank_accounts_id': _get_default_accounts,
3041+ 'sale_tax': _get_sale_tax,
3042+ 'purchase_tax': _get_purchase_tax,
3043+ 'code_digits': 6,
3044+ 'seq_journal': True
3045+ }
3046+
3047+ def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
3048+ 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)
3049+ cmp_select = []
3050+ company_ids = self.pool.get('res.company').search(cr, uid, [], context=context)
3051+ #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)
3052+ 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",))
3053+ configured_cmp = [r[0] for r in cr.fetchall()]
3054+ unconfigured_cmp = list(set(company_ids)-set(configured_cmp))
3055+ for field in res['fields']:
3056+ if field == 'company_id':
3057+ res['fields'][field]['domain'] = [('id','in',unconfigured_cmp)]
3058+ res['fields'][field]['selection'] = [('', '')]
3059+ if unconfigured_cmp:
3060+ cmp_select = [(line.id, line.name) for line in self.pool.get('res.company').browse(cr, uid, unconfigured_cmp)]
3061+ res['fields'][field]['selection'] = cmp_select
3062+ return res
3063+
3064+ def execute(self, cr, uid, ids, context=None):
3065+ obj_multi = self.browse(cr, uid, ids[0])
3066+ obj_acc = self.pool.get('account.account')
3067+ obj_acc_tax = self.pool.get('account.tax')
3068+ obj_journal = self.pool.get('account.journal')
3069+ obj_acc_template = self.pool.get('account.account.template')
3070+ obj_fiscal_position_template = self.pool.get('account.fiscal.position.template')
3071+ obj_fiscal_position = self.pool.get('account.fiscal.position')
3072+ obj_data = self.pool.get('ir.model.data')
3073+ analytic_journal_obj = self.pool.get('account.analytic.journal')
3074+ obj_tax_code = self.pool.get('account.tax.code')
3075+ obj_tax_code_template = self.pool.get('account.tax.code.template')
3076+ ir_values_obj = self.pool.get('ir.values')
3077+ # Creating Account
3078+ obj_acc_root = obj_multi.chart_template_id.account_root_id
3079+ tax_code_root_id = obj_multi.chart_template_id.tax_code_root_id.id
3080+ company_id = obj_multi.company_id.id
3081+
3082+ #new code
3083+ acc_template_ref = {}
3084+ tax_template_ref = {}
3085+ tax_code_template_ref = {}
3086+ todo_dict = {}
3087+
3088+ #create all the tax code
3089+ children_tax_code_template = obj_tax_code_template.search(cr, uid, [('parent_id','child_of',[tax_code_root_id])], order='id')
3090+ children_tax_code_template.sort()
3091+ for tax_code_template in obj_tax_code_template.browse(cr, uid, children_tax_code_template, context=context):
3092+ vals = {
3093+ 'name': (tax_code_root_id == tax_code_template.id) and obj_multi.company_id.name or tax_code_template.name,
3094+ 'code': tax_code_template.code,
3095+ 'info': tax_code_template.info,
3096+ '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,
3097+ 'company_id': company_id,
3098+ 'sign': tax_code_template.sign,
3099+ }
3100+ new_tax_code = obj_tax_code.create(cr, uid, vals)
3101+ #recording the new tax code to do the mapping
3102+ tax_code_template_ref[tax_code_template.id] = new_tax_code
3103+
3104+ #create all the tax
3105+ tax_template_to_tax = {}
3106+ for tax in obj_multi.chart_template_id.tax_template_ids:
3107+ #create it
3108+ vals_tax = {
3109+ 'name':tax.name,
3110+ 'sequence': tax.sequence,
3111+ 'amount':tax.amount,
3112+ 'type':tax.type,
3113+ 'applicable_type': tax.applicable_type,
3114+ 'domain':tax.domain,
3115+ 'parent_id': tax.parent_id and ((tax.parent_id.id in tax_template_ref) and tax_template_ref[tax.parent_id.id]) or False,
3116+ 'child_depend': tax.child_depend,
3117+ 'python_compute': tax.python_compute,
3118+ 'python_compute_inv': tax.python_compute_inv,
3119+ 'python_applicable': tax.python_applicable,
3120+ '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,
3121+ '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,
3122+ 'base_sign': tax.base_sign,
3123+ 'tax_sign': tax.tax_sign,
3124+ '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,
3125+ '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,
3126+ 'ref_base_sign': tax.ref_base_sign,
3127+ 'ref_tax_sign': tax.ref_tax_sign,
3128+ 'include_base_amount': tax.include_base_amount,
3129+ 'description':tax.description,
3130+ 'company_id': company_id,
3131+ 'type_tax_use': tax.type_tax_use,
3132+ 'price_include': tax.price_include
3133+ }
3134+ new_tax = obj_acc_tax.create(cr, uid, vals_tax)
3135+ tax_template_to_tax[tax.id] = new_tax
3136+ #as the accounts have not been created yet, we have to wait before filling these fields
3137+ todo_dict[new_tax] = {
3138+ 'account_collected_id': tax.account_collected_id and tax.account_collected_id.id or False,
3139+ 'account_paid_id': tax.account_paid_id and tax.account_paid_id.id or False,
3140+ }
3141+ tax_template_ref[tax.id] = new_tax
3142+ #deactivate the parent_store functionnality on account_account for rapidity purpose
3143+ ctx = context and context.copy() or {}
3144+ ctx['defer_parent_store_computation'] = True
3145+
3146+ children_acc_template = obj_acc_template.search(cr, uid, [('parent_id','child_of',[obj_acc_root.id]),('nocreate','!=',True)])
3147+ children_acc_template.sort()
3148+ for account_template in obj_acc_template.browse(cr, uid, children_acc_template, context=context):
3149+ tax_ids = []
3150+ for tax in account_template.tax_ids:
3151+ tax_ids.append(tax_template_ref[tax.id])
3152+ #create the account_account
3153+
3154+ dig = obj_multi.code_digits
3155+ code_main = account_template.code and len(account_template.code) or 0
3156+ code_acc = account_template.code or ''
3157+ if code_main>0 and code_main<=dig and account_template.type != 'view':
3158+ code_acc=str(code_acc) + (str('0'*(dig-code_main)))
3159+ vals={
3160+ 'name': (obj_acc_root.id == account_template.id) and obj_multi.company_id.name or account_template.name,
3161+ 'currency_id': account_template.currency_id and account_template.currency_id.id or False,
3162+ 'code': code_acc,
3163+ 'type': account_template.type,
3164+ 'user_type': account_template.user_type and account_template.user_type.id or False,
3165+ 'reconcile': account_template.reconcile,
3166+ 'shortcut': account_template.shortcut,
3167+ 'note': account_template.note,
3168+ '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,
3169+ 'tax_ids': [(6,0,tax_ids)],
3170+ 'company_id': company_id,
3171+ }
3172+ new_account = obj_acc.create(cr, uid, vals, context=ctx)
3173+ acc_template_ref[account_template.id] = new_account
3174+
3175+
3176+ #reactivate the parent_store functionnality on account_account
3177+ obj_acc._parent_store_compute(cr)
3178+
3179+ for key,value in todo_dict.items():
3180+ if value['account_collected_id'] or value['account_paid_id']:
3181+ obj_acc_tax.write(cr, uid, [key], {
3182+ 'account_collected_id': acc_template_ref.get(value['account_collected_id'], False),
3183+ 'account_paid_id': acc_template_ref.get(value['account_paid_id'], False),
3184+ })
3185+
3186+ # Creating Journals
3187+ data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_sp_journal_view')])
3188+ data = obj_data.browse(cr, uid, data_id[0], context=context)
3189+ view_id = data.res_id
3190+
3191+ #Sales Journal
3192+ analytical_sale_ids = analytic_journal_obj.search(cr,uid,[('type','=','sale')])
3193+ analytical_journal_sale = analytical_sale_ids and analytical_sale_ids[0] or False
3194+
3195+ vals_journal = {
3196+ 'name': _('Sales Journal'),
3197+ 'type': 'sale',
3198+ 'code': _('SAJ'),
3199+ 'view_id': view_id,
3200+ 'company_id': company_id,
3201+ 'analytic_journal_id': analytical_journal_sale,
3202+ }
3203+
3204+ if obj_multi.chart_template_id.property_account_receivable:
3205+ vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
3206+ vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
3207+
3208+ obj_journal.create(cr,uid,vals_journal)
3209+
3210+ # Purchase Journal
3211+ analytical_purchase_ids = analytic_journal_obj.search(cr,uid,[('type','=','purchase')])
3212+ analytical_journal_purchase = analytical_purchase_ids and analytical_purchase_ids[0] or False
3213+
3214+ vals_journal = {
3215+ 'name': _('Purchase Journal'),
3216+ 'type': 'purchase',
3217+ 'code': _('EXJ'),
3218+ 'view_id': view_id,
3219+ 'company_id': company_id,
3220+ 'analytic_journal_id': analytical_journal_purchase,
3221+ }
3222+
3223+ if obj_multi.chart_template_id.property_account_payable:
3224+ vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3225+ vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3226+ obj_journal.create(cr,uid,vals_journal)
3227+
3228+ # Creating Journals Sales Refund and Purchase Refund
3229+ data_id = obj_data.search(cr, uid, [('model', '=', 'account.journal.view'), ('name', '=', 'account_sp_refund_journal_view')], context=context)
3230+ data = obj_data.browse(cr, uid, data_id[0], context=context)
3231+ view_id = data.res_id
3232+
3233+ #Sales Refund Journal
3234+ vals_journal = {
3235+ 'name': _('Sales Refund Journal'),
3236+ 'type': 'sale_refund',
3237+ 'code': _('SCNJ'),
3238+ 'view_id': view_id,
3239+ 'analytic_journal_id': analytical_journal_sale,
3240+ 'company_id': company_id
3241+ }
3242+
3243+ if obj_multi.chart_template_id.property_account_receivable:
3244+ vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
3245+ vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
3246+
3247+ obj_journal.create(cr, uid, vals_journal, context=context)
3248+
3249+ # Purchase Refund Journal
3250+ vals_journal = {
3251+ 'name': _('Purchase Refund Journal'),
3252+ 'type': 'purchase_refund',
3253+ 'code': _('ECNJ'),
3254+ 'view_id': view_id,
3255+ 'analytic_journal_id': analytical_journal_purchase,
3256+ 'company_id': company_id
3257+ }
3258+
3259+ if obj_multi.chart_template_id.property_account_payable:
3260+ vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3261+ vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
3262+
3263+ obj_journal.create(cr, uid, vals_journal, context=context)
3264+
3265+ # Miscellaneous Journal
3266+ data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_view')])
3267+ data = obj_data.browse(cr, uid, data_id[0], context=context)
3268+ view_id = data.res_id
3269+
3270+ analytical_miscellaneous_ids = analytic_journal_obj.search(cr, uid, [('type', '=', 'situation')], context=context)
3271+ analytical_journal_miscellaneous = analytical_miscellaneous_ids and analytical_miscellaneous_ids[0] or False
3272+
3273+ vals_journal = {
3274+ 'name': _('Miscellaneous Journal'),
3275+ 'type': 'general',
3276+ 'code': _('MISC'),
3277+ 'view_id': view_id,
3278+ 'analytic_journal_id': analytical_journal_miscellaneous,
3279+ 'company_id': company_id
3280+ }
3281+
3282+ obj_journal.create(cr, uid, vals_journal, context=context)
3283+
3284+ # Opening Entries Journal
3285+ if obj_multi.chart_template_id.property_account_income_opening and obj_multi.chart_template_id.property_account_expense_opening:
3286+ vals_journal = {
3287+ 'name': _('Opening Entries Journal'),
3288+ 'type': 'situation',
3289+ 'code': _('OPEJ'),
3290+ 'view_id': view_id,
3291+ 'company_id': company_id,
3292+ 'centralisation': True,
3293+ 'default_credit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_income_opening.id],
3294+ 'default_debit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_expense_opening.id]
3295+ }
3296+ obj_journal.create(cr, uid, vals_journal, context=context)
3297+
3298+ # Bank Journals
3299+ data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
3300+ data = obj_data.browse(cr, uid, data_id[0], context=context)
3301+ view_id_cash = data.res_id
3302+
3303+ data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view_multi')])
3304+ data = obj_data.browse(cr, uid, data_id[0], context=context)
3305+ view_id_cur = data.res_id
3306+ ref_acc_bank = obj_multi.chart_template_id.bank_account_view_id
3307+
3308+ current_num = 1
3309+ valid = True
3310+ for line in obj_multi.bank_accounts_id:
3311+ #create the account_account for this bank journal
3312+ tmp = line.acc_name
3313+ dig = obj_multi.code_digits
3314+ if not ref_acc_bank.code:
3315+ raise osv.except_osv(_('Configuration Error !'), _('The bank account defined on the selected chart of account hasn\'t a code.'))
3316+ while True:
3317+ new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num)
3318+ ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', company_id)])
3319+ if not ids:
3320+ break
3321+ else:
3322+ current_num += 1
3323+ vals = {
3324+ 'name': tmp,
3325+ 'currency_id': line.currency_id and line.currency_id.id or False,
3326+ 'code': new_code,
3327+ 'type': 'liquidity',
3328+ 'user_type': account_template.user_type and account_template.user_type.id or False,
3329+ 'reconcile': True,
3330+ 'parent_id': acc_template_ref[ref_acc_bank.id] or False,
3331+ 'company_id': company_id,
3332+ }
3333+ acc_cash_id = obj_acc.create(cr,uid,vals)
3334+
3335+ #create the bank journal
3336+ vals_journal = {
3337+ 'name': vals['name'],
3338+ 'code': _('BNK') + str(current_num),
3339+ 'type': line.account_type == 'cash' and 'cash' or 'bank',
3340+ 'company_id': company_id,
3341+ 'analytic_journal_id': False,
3342+ 'currency_id': False,
3343+ }
3344+ if line.currency_id:
3345+ vals_journal['view_id'] = view_id_cur
3346+ vals_journal['currency'] = line.currency_id.id
3347+ else:
3348+ vals_journal['view_id'] = view_id_cash
3349+ vals_journal['default_credit_account_id'] = acc_cash_id
3350+ vals_journal['default_debit_account_id'] = acc_cash_id
3351+ obj_journal.create(cr, uid, vals_journal)
3352+ current_num += 1
3353+ valid = True
3354+
3355+ #create the properties
3356+ property_obj = self.pool.get('ir.property')
3357+ fields_obj = self.pool.get('ir.model.fields')
3358+
3359+ todo_list = [
3360+ ('property_account_receivable','res.partner','account.account'),
3361+ ('property_account_payable','res.partner','account.account'),
3362+ ('property_account_expense_categ','product.category','account.account'),
3363+ ('property_account_income_categ','product.category','account.account'),
3364+ ('property_account_expense','product.template','account.account'),
3365+ ('property_account_income','product.template','account.account'),
3366+ ('property_reserve_and_surplus_account','res.company','account.account')
3367+ ]
3368+ for record in todo_list:
3369+ r = []
3370+ r = property_obj.search(cr, uid, [('name','=', record[0] ),('company_id','=',company_id)])
3371+ account = getattr(obj_multi.chart_template_id, record[0])
3372+ field = fields_obj.search(cr, uid, [('name','=',record[0]),('model','=',record[1]),('relation','=',record[2])])
3373+ vals = {
3374+ 'name': record[0],
3375+ 'company_id': company_id,
3376+ 'fields_id': field[0],
3377+ 'value': account and 'account.account,' + str(acc_template_ref[account.id]) or False,
3378+ }
3379+
3380+ if r:
3381+ #the property exist: modify it
3382+ property_obj.write(cr, uid, r, vals)
3383+ else:
3384+ #create the property
3385+ property_obj.create(cr, uid, vals)
3386+
3387+ fp_ids = obj_fiscal_position_template.search(cr, uid, [('chart_template_id', '=', obj_multi.chart_template_id.id)])
3388+
3389+ if fp_ids:
3390+ obj_tax_fp = self.pool.get('account.fiscal.position.tax')
3391+ obj_ac_fp = self.pool.get('account.fiscal.position.account')
3392+
3393+ for position in obj_fiscal_position_template.browse(cr, uid, fp_ids, context=context):
3394+
3395+ vals_fp = {
3396+ 'company_id': company_id,
3397+ 'name': position.name,
3398+ }
3399+ new_fp = obj_fiscal_position.create(cr, uid, vals_fp)
3400+
3401+ for tax in position.tax_ids:
3402+ vals_tax = {
3403+ 'tax_src_id': tax_template_ref[tax.tax_src_id.id],
3404+ 'tax_dest_id': tax.tax_dest_id and tax_template_ref[tax.tax_dest_id.id] or False,
3405+ 'position_id': new_fp,
3406+ }
3407+ obj_tax_fp.create(cr, uid, vals_tax)
3408+
3409+ for acc in position.account_ids:
3410+ vals_acc = {
3411+ 'account_src_id': acc_template_ref[acc.account_src_id.id],
3412+ 'account_dest_id': acc_template_ref[acc.account_dest_id.id],
3413+ 'position_id': new_fp,
3414+ }
3415+ obj_ac_fp.create(cr, uid, vals_acc)
3416+
3417+ if obj_multi.sale_tax:
3418+ ir_values_obj.set(cr, uid, key='default', key2=False, name="taxes_id", company=obj_multi.company_id.id,
3419+ models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.sale_tax.id]])
3420+ if obj_multi.purchase_tax:
3421+ ir_values_obj.set(cr, uid, key='default', key2=False, name="supplier_taxes_id", company=obj_multi.company_id.id,
3422+ models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.purchase_tax.id]])
3423+
3424+wizard_multi_charts_accounts()
3425+
3426+class account_bank_accounts_wizard(osv.osv_memory):
3427+ _name='account.bank.accounts.wizard'
3428+
3429+ _columns = {
3430+ 'acc_name': fields.char('Account Name.', size=64, required=True),
3431+ 'bank_account_id': fields.many2one('wizard.multi.charts.accounts', 'Bank Account', required=True),
3432+ 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
3433+ 'account_type': fields.selection([('cash','Cash'), ('check','Check'), ('bank','Bank')], 'Account Type', size=32),
3434+ }
3435+
3436+account_bank_accounts_wizard()
3437+
3438+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3439
3440=== added file 'account/account_analytic_line.py'
3441--- account/account_analytic_line.py 1970-01-01 00:00:00 +0000
3442+++ account/account_analytic_line.py 2011-10-06 16:09:39 +0000
3443@@ -0,0 +1,162 @@
3444+# -*- coding: utf-8 -*-
3445+##############################################################################
3446+#
3447+# OpenERP, Open Source Management Solution
3448+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
3449+#
3450+# This program is free software: you can redistribute it and/or modify
3451+# it under the terms of the GNU Affero General Public License as
3452+# published by the Free Software Foundation, either version 3 of the
3453+# License, or (at your option) any later version.
3454+#
3455+# This program is distributed in the hope that it will be useful,
3456+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3457+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3458+# GNU Affero General Public License for more details.
3459+#
3460+# You should have received a copy of the GNU Affero General Public License
3461+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3462+#
3463+##############################################################################
3464+
3465+import time
3466+
3467+from osv import fields
3468+from osv import osv
3469+from tools.translate import _
3470+
3471+class account_analytic_line(osv.osv):
3472+ _inherit = 'account.analytic.line'
3473+ _description = 'Analytic Line'
3474+ _columns = {
3475+ 'product_uom_id': fields.many2one('product.uom', 'UoM'),
3476+ 'product_id': fields.many2one('product.product', 'Product'),
3477+ 'general_account_id': fields.many2one('account.account', 'General Account', required=True, ondelete='restrict'),
3478+ 'move_id': fields.many2one('account.move.line', 'Move Line', ondelete='cascade', select=True),
3479+ 'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal', required=True, ondelete='restrict', select=True),
3480+ 'code': fields.char('Code', size=8),
3481+ 'ref': fields.char('Ref.', size=64),
3482+ '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),
3483+ '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),
3484+ }
3485+
3486+ _defaults = {
3487+ 'date': lambda *a: time.strftime('%Y-%m-%d'),
3488+ 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', context=c),
3489+ }
3490+ _order = 'date desc'
3491+
3492+ def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
3493+ if context is None:
3494+ context = {}
3495+ if context.get('from_date',False):
3496+ args.append(['date', '>=', context['from_date']])
3497+ if context.get('to_date',False):
3498+ args.append(['date','<=', context['to_date']])
3499+ return super(account_analytic_line, self).search(cr, uid, args, offset, limit,
3500+ order, context=context, count=count)
3501+
3502+ def _check_company(self, cr, uid, ids, context=None):
3503+ lines = self.browse(cr, uid, ids, context=context)
3504+ for l in lines:
3505+ if l.move_id and not l.account_id.company_id.id == l.move_id.account_id.company_id.id:
3506+ return False
3507+ return True
3508+
3509+ # Compute the cost based on the price type define into company
3510+ # property_valuation_price_type property
3511+ def on_change_unit_amount(self, cr, uid, id, prod_id, quantity, company_id,
3512+ unit=False, journal_id=False, context=None):
3513+ if context==None:
3514+ context={}
3515+ if not journal_id:
3516+ j_ids = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=','purchase')])
3517+ journal_id = j_ids and j_ids[0] or False
3518+ if not journal_id or not prod_id:
3519+ return {}
3520+ product_obj = self.pool.get('product.product')
3521+ analytic_journal_obj =self.pool.get('account.analytic.journal')
3522+ product_price_type_obj = self.pool.get('product.price.type')
3523+ j_id = analytic_journal_obj.browse(cr, uid, journal_id, context=context)
3524+ prod = product_obj.browse(cr, uid, prod_id, context=context)
3525+ result = 0.0
3526+ if prod_id:
3527+ unit = prod.uom_id.id
3528+ if j_id.type == 'purchase':
3529+ unit = prod.uom_po_id.id
3530+ if j_id.type <> 'sale':
3531+ a = prod.product_tmpl_id.property_account_expense.id
3532+ if not a:
3533+ a = prod.categ_id.property_account_expense_categ.id
3534+ if not a:
3535+ raise osv.except_osv(_('Error !'),
3536+ _('There is no expense account defined ' \
3537+ 'for this product: "%s" (id:%d)') % \
3538+ (prod.name, prod.id,))
3539+ else:
3540+ a = prod.product_tmpl_id.property_account_income.id
3541+ if not a:
3542+ a = prod.categ_id.property_account_income_categ.id
3543+ if not a:
3544+ raise osv.except_osv(_('Error !'),
3545+ _('There is no income account defined ' \
3546+ 'for this product: "%s" (id:%d)') % \
3547+ (prod.name, prod_id,))
3548+
3549+ flag = False
3550+ # Compute based on pricetype
3551+ product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','standard_price')], context=context)
3552+ pricetype = product_price_type_obj.browse(cr, uid, product_price_type_ids, context=context)[0]
3553+ if journal_id:
3554+ journal = analytic_journal_obj.browse(cr, uid, journal_id, context=context)
3555+ if journal.type == 'sale':
3556+ product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','list_price')], context)
3557+ if product_price_type_ids:
3558+ pricetype = product_price_type_obj.browse(cr, uid, product_price_type_ids, context=context)[0]
3559+ # Take the company currency as the reference one
3560+ if pricetype.field == 'list_price':
3561+ flag = True
3562+ ctx = context.copy()
3563+ if unit:
3564+ # price_get() will respect a 'uom' in its context, in order
3565+ # to return a default price for those units
3566+ ctx['uom'] = unit
3567+ amount_unit = prod.price_get(pricetype.field, context=ctx)[prod.id]
3568+ prec = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
3569+ amount = amount_unit * quantity or 1.0
3570+ result = round(amount, prec)
3571+ if not flag:
3572+ result *= -1
3573+ return {'value': {
3574+ 'amount': result,
3575+ 'general_account_id': a,
3576+ 'product_uom_id': unit
3577+ }
3578+ }
3579+
3580+ def view_header_get(self, cr, user, view_id, view_type, context=None):
3581+ if context is None:
3582+ context = {}
3583+ if context.get('account_id', False):
3584+ # account_id in context may also be pointing to an account.account.id
3585+ cr.execute('select name from account_analytic_account where id=%s', (context['account_id'],))
3586+ res = cr.fetchone()
3587+ if res:
3588+ res = _('Entries: ')+ (res[0] or '')
3589+ return res
3590+ return False
3591+
3592+account_analytic_line()
3593+
3594+class res_partner(osv.osv):
3595+ """ Inherits partner and adds contract information in the partner form """
3596+ _inherit = 'res.partner'
3597+
3598+ _columns = {
3599+ 'contract_ids': fields.one2many('account.analytic.account', \
3600+ 'partner_id', 'Contracts', readonly=True),
3601+ }
3602+
3603+res_partner()
3604+
3605+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3606
3607=== added file 'account/account_assert_test.xml'
3608--- account/account_assert_test.xml 1970-01-01 00:00:00 +0000
3609+++ account/account_assert_test.xml 2011-10-06 16:09:39 +0000
3610@@ -0,0 +1,8 @@
3611+<?xml version="1.0" encoding="utf-8"?>
3612+<openerp>
3613+ <data>
3614+ <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">
3615+ <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)"/>
3616+ </assert>
3617+ </data>
3618+</openerp>
3619
3620=== added file 'account/account_bank.py'
3621--- account/account_bank.py 1970-01-01 00:00:00 +0000
3622+++ account/account_bank.py 2011-10-06 16:09:39 +0000
3623@@ -0,0 +1,103 @@
3624+# -*- coding: utf-8 -*-
3625+##############################################################################
3626+#
3627+# OpenERP, Open Source Management Solution
3628+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
3629+#
3630+# This program is free software: you can redistribute it and/or modify
3631+# it under the terms of the GNU Affero General Public License as
3632+# published by the Free Software Foundation, either version 3 of the
3633+# License, or (at your option) any later version.
3634+#
3635+# This program is distributed in the hope that it will be useful,
3636+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3637+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3638+# GNU Affero General Public License for more details.
3639+#
3640+# You should have received a copy of the GNU Affero General Public License
3641+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3642+#
3643+##############################################################################
3644+
3645+from tools.translate import _
3646+from osv import fields, osv
3647+
3648+class bank(osv.osv):
3649+ _inherit = "res.partner.bank"
3650+ _columns = {
3651+ 'journal_id': fields.many2one('account.journal', 'Account Journal', help="This journal will be created automatically for this bank account when you save the record"),
3652+ }
3653+ def create(self, cr, uid, data, context={}):
3654+ result = super(bank, self).create(cr, uid, data, context=context)
3655+ self.post_write(cr, uid, [result], context=context)
3656+ return result
3657+
3658+ def write(self, cr, uid, ids, data, context={}):
3659+ result = super(bank, self).write(cr, uid, ids, data, context=context)
3660+ self.post_write(cr, uid, ids, context=context)
3661+ return result
3662+
3663+ def post_write(self, cr, uid, ids, context={}):
3664+ obj_acc = self.pool.get('account.account')
3665+ obj_data = self.pool.get('ir.model.data')
3666+ for bank in self.browse(cr, uid, ids, context):
3667+ if bank.company_id and not bank.journal_id:
3668+ # Find the code and parent of the bank account to create
3669+ dig = 6
3670+ current_num = 1
3671+ ids = obj_acc.search(cr, uid, [('type','=','liquidity')], context=context)
3672+ # No liquidity account exists, no template available
3673+ if not ids: continue
3674+
3675+ ref_acc_bank_temp = obj_acc.browse(cr, uid, ids[0], context=context)
3676+ ref_acc_bank = ref_acc_bank_temp.parent_id
3677+ while True:
3678+ new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num)
3679+ ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', bank.company_id.id)])
3680+ if not ids:
3681+ break
3682+ current_num += 1
3683+
3684+ acc = {
3685+ 'name': (bank.bank_name or '')+' '+bank.acc_number,
3686+ 'currency_id': bank.company_id.currency_id.id,
3687+ 'code': new_code,
3688+ 'type': 'liquidity',
3689+ 'user_type': ref_acc_bank_temp.user_type.id,
3690+ 'reconcile': False,
3691+ 'parent_id': ref_acc_bank.id,
3692+ 'company_id': bank.company_id.id,
3693+ }
3694+ acc_bank_id = obj_acc.create(cr,uid,acc,context=context)
3695+
3696+ # Get the journal view id
3697+ data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
3698+ data = obj_data.browse(cr, uid, data_id[0], context=context)
3699+ view_id_cash = data.res_id
3700+
3701+ jour_obj = self.pool.get('account.journal')
3702+ new_code = 1
3703+ while True:
3704+ code = _('BNK')+str(new_code)
3705+ ids = jour_obj.search(cr, uid, [('code','=',code)], context=context)
3706+ if not ids:
3707+ break
3708+ new_code += 1
3709+
3710+ #create the bank journal
3711+ vals_journal = {
3712+ 'name': (bank.bank_name or '')+' '+bank.acc_number,
3713+ 'code': code,
3714+ 'type': 'bank',
3715+ 'company_id': bank.company_id.id,
3716+ 'analytic_journal_id': False,
3717+ 'currency_id': False,
3718+ 'default_credit_account_id': acc_bank_id,
3719+ 'default_debit_account_id': acc_bank_id,
3720+ 'view_id': view_id_cash
3721+ }
3722+ journal_id = jour_obj.create(cr, uid, vals_journal, context=context)
3723+
3724+ self.write(cr, uid, [bank.id], {'journal_id': journal_id}, context=context)
3725+ return True
3726+
3727
3728=== added file 'account/account_bank_statement.py'
3729--- account/account_bank_statement.py 1970-01-01 00:00:00 +0000
3730+++ account/account_bank_statement.py 2011-10-06 16:09:39 +0000
3731@@ -0,0 +1,484 @@
3732+# -*- coding: utf-8 -*-
3733+##############################################################################
3734+#
3735+# OpenERP, Open Source Management Solution
3736+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
3737+#
3738+# This program is free software: you can redistribute it and/or modify
3739+# it under the terms of the GNU Affero General Public License as
3740+# published by the Free Software Foundation, either version 3 of the
3741+# License, or (at your option) any later version.
3742+#
3743+# This program is distributed in the hope that it will be useful,
3744+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3745+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3746+# GNU Affero General Public License for more details.
3747+#
3748+# You should have received a copy of the GNU Affero General Public License
3749+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3750+#
3751+##############################################################################
3752+
3753+import time
3754+
3755+from osv import fields, osv
3756+from tools.translate import _
3757+import decimal_precision as dp
3758+
3759+class account_bank_statement(osv.osv):
3760+
3761+ def create(self, cr, uid, vals, context=None):
3762+ seq = 0
3763+ if 'line_ids' in vals:
3764+ for line in vals['line_ids']:
3765+ seq += 1
3766+ line[2]['sequence'] = seq
3767+ vals[seq - 1] = line
3768+ return super(account_bank_statement, self).create(cr, uid, vals, context=context)
3769+
3770+ def write(self, cr, uid, ids, vals, context=None):
3771+ res = super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
3772+ account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
3773+ for statement in self.browse(cr, uid, ids, context):
3774+ seq = 0
3775+ for line in statement.line_ids:
3776+ seq += 1
3777+ account_bank_statement_line_obj.write(cr, uid, [line.id], {'sequence': seq}, context=context)
3778+ return res
3779+
3780+ def _default_journal_id(self, cr, uid, context=None):
3781+ if context is None:
3782+ context = {}
3783+ journal_pool = self.pool.get('account.journal')
3784+ journal_type = context.get('journal_type', False)
3785+ journal_id = False
3786+ if journal_type:
3787+ ids = journal_pool.search(cr, uid, [('type', '=', journal_type)])
3788+ if ids:
3789+ journal_id = ids[0]
3790+ return journal_id
3791+
3792+ def _end_balance(self, cursor, user, ids, name, attr, context=None):
3793+ res_currency_obj = self.pool.get('res.currency')
3794+ res_users_obj = self.pool.get('res.users')
3795+ res = {}
3796+
3797+ company_currency_id = res_users_obj.browse(cursor, user, user,
3798+ context=context).company_id.currency_id.id
3799+
3800+ statements = self.browse(cursor, user, ids, context=context)
3801+ for statement in statements:
3802+ res[statement.id] = statement.balance_start
3803+ currency_id = statement.currency.id
3804+ for line in statement.move_line_ids:
3805+ if line.debit > 0:
3806+ if line.account_id.id == \
3807+ statement.journal_id.default_debit_account_id.id:
3808+ res[statement.id] += res_currency_obj.compute(cursor,
3809+ user, company_currency_id, currency_id,
3810+ line.debit, context=context)
3811+ else:
3812+ if line.account_id.id == \
3813+ statement.journal_id.default_credit_account_id.id:
3814+ res[statement.id] -= res_currency_obj.compute(cursor,
3815+ user, company_currency_id, currency_id,
3816+ line.credit, context=context)
3817+
3818+ if statement.state in ('draft', 'open'):
3819+ for line in statement.line_ids:
3820+ res[statement.id] += line.amount
3821+ for r in res:
3822+ res[r] = round(res[r], 2)
3823+ return res
3824+
3825+ def _get_period(self, cr, uid, context=None):
3826+ periods = self.pool.get('account.period').find(cr, uid)
3827+ if periods:
3828+ return periods[0]
3829+ return False
3830+
3831+ def _currency(self, cursor, user, ids, name, args, context=None):
3832+ res = {}
3833+ res_currency_obj = self.pool.get('res.currency')
3834+ res_users_obj = self.pool.get('res.users')
3835+ default_currency = res_users_obj.browse(cursor, user,
3836+ user, context=context).company_id.currency_id
3837+ for statement in self.browse(cursor, user, ids, context=context):
3838+ currency = statement.journal_id.currency
3839+ if not currency:
3840+ currency = default_currency
3841+ res[statement.id] = currency.id
3842+ currency_names = {}
3843+ for currency_id, currency_name in res_currency_obj.name_get(cursor,
3844+ user, [x for x in res.values()], context=context):
3845+ currency_names[currency_id] = currency_name
3846+ for statement_id in res.keys():
3847+ currency_id = res[statement_id]
3848+ res[statement_id] = (currency_id, currency_names[currency_id])
3849+ return res
3850+
3851+ def _get_statement(self, cr, uid, ids, context=None):
3852+ result = {}
3853+ for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
3854+ result[line.statement_id.id] = True
3855+ return result.keys()
3856+
3857+ _order = "date desc, id desc"
3858+ _name = "account.bank.statement"
3859+ _description = "Bank Statement"
3860+ _columns = {
3861+ '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
3862+ 'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}),
3863+ 'journal_id': fields.many2one('account.journal', 'Journal', required=True,
3864+ readonly=True, states={'draft':[('readonly',False)]}),
3865+ 'period_id': fields.many2one('account.period', 'Period', required=True,
3866+ states={'confirm':[('readonly', True)]}),
3867+ 'balance_start': fields.float('Starting Balance', digits_compute=dp.get_precision('Account'),
3868+ states={'confirm':[('readonly',True)]}),
3869+ 'balance_end_real': fields.float('Ending Balance', digits_compute=dp.get_precision('Account'),
3870+ states={'confirm': [('readonly', True)]}),
3871+ 'balance_end': fields.function(_end_balance,
3872+ store = {
3873+ 'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
3874+ 'account.bank.statement.line': (_get_statement, ['amount'], 10),
3875+ },
3876+ string="Computed Balance", help='Balance as calculated based on Starting Balance and transaction lines'),
3877+ 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
3878+ 'line_ids': fields.one2many('account.bank.statement.line',
3879+ 'statement_id', 'Statement lines',
3880+ states={'confirm':[('readonly', True)]}),
3881+ 'move_line_ids': fields.one2many('account.move.line', 'statement_id',
3882+ 'Entry lines', states={'confirm':[('readonly',True)]}),
3883+ 'state': fields.selection([('draft', 'New'),
3884+ ('open','Open'), # used by cash statements
3885+ ('confirm', 'Closed')],
3886+ 'State', required=True, readonly="1",
3887+ help='When new statement is created the state will be \'Draft\'.\n'
3888+ 'And after getting confirmation from the bank it will be in \'Confirmed\' state.'),
3889+ 'currency': fields.function(_currency, string='Currency',
3890+ type='many2one', relation='res.currency'),
3891+ '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.'),
3892+ }
3893+
3894+ _defaults = {
3895+ 'name': "/",
3896+ 'date': lambda *a: time.strftime('%Y-%m-%d'),
3897+ 'state': 'draft',
3898+ 'journal_id': _default_journal_id,
3899+ 'period_id': _get_period,
3900+ 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.bank.statement',context=c),
3901+ }
3902+
3903+ def onchange_date(self, cr, user, ids, date, context=None):
3904+ """
3905+ Returns a dict that contains new values and context
3906+ @param cr: A database cursor
3907+ @param user: ID of the user currently logged in
3908+ @param date: latest value from user input for field date
3909+ @param args: other arguments
3910+ @param context: context arguments, like lang, time zone
3911+ @return: Returns a dict which contains new values, and context
3912+ """
3913+ res = {}
3914+ period_pool = self.pool.get('account.period')
3915+
3916+ if context is None:
3917+ context = {}
3918+
3919+ pids = period_pool.search(cr, user, [('date_start','<=',date), ('date_stop','>=',date)])
3920+ if pids:
3921+ res.update({
3922+ 'period_id':pids[0]
3923+ })
3924+ context.update({
3925+ 'period_id':pids[0]
3926+ })
3927+
3928+ return {
3929+ 'value':res,
3930+ 'context':context,
3931+ }
3932+
3933+ def button_dummy(self, cr, uid, ids, context=None):
3934+ return self.write(cr, uid, ids, {}, context=context)
3935+
3936+ def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id, st_line_number, context=None):
3937+ if context is None:
3938+ context = {}
3939+ res_currency_obj = self.pool.get('res.currency')
3940+ account_move_obj = self.pool.get('account.move')
3941+ account_move_line_obj = self.pool.get('account.move.line')
3942+ account_bank_statement_line_obj = self.pool.get('account.bank.statement.line')
3943+ st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id, context=context)
3944+ st = st_line.statement_id
3945+
3946+ context.update({'date': st_line.date})
3947+
3948+ move_id = account_move_obj.create(cr, uid, {
3949+ 'journal_id': st.journal_id.id,
3950+ 'period_id': st.period_id.id,
3951+ 'date': st_line.date,
3952+ 'name': st_line_number,
3953+ }, context=context)
3954+ account_bank_statement_line_obj.write(cr, uid, [st_line.id], {
3955+ 'move_ids': [(4, move_id, False)]
3956+ })
3957+
3958+ torec = []
3959+ if st_line.amount >= 0:
3960+ account_id = st.journal_id.default_credit_account_id.id
3961+ else:
3962+ account_id = st.journal_id.default_debit_account_id.id
3963+
3964+ acc_cur = ((st_line.amount<=0) and st.journal_id.default_debit_account_id) or st_line.account_id
3965+ context.update({
3966+ 'res.currency.compute.account': acc_cur,
3967+ })
3968+ amount = res_currency_obj.compute(cr, uid, st.currency.id,
3969+ company_currency_id, st_line.amount, context=context)
3970+
3971+ val = {
3972+ 'name': st_line.name,
3973+ 'date': st_line.date,
3974+ 'ref': st_line.ref,
3975+ 'move_id': move_id,
3976+ 'partner_id': ((st_line.partner_id) and st_line.partner_id.id) or False,
3977+ 'account_id': (st_line.account_id) and st_line.account_id.id,
3978+ 'credit': ((amount>0) and amount) or 0.0,
3979+ 'debit': ((amount<0) and -amount) or 0.0,
3980+ 'statement_id': st.id,
3981+ 'journal_id': st.journal_id.id,
3982+ 'period_id': st.period_id.id,
3983+ 'currency_id': st.currency.id,
3984+ 'analytic_account_id': st_line.analytic_account_id and st_line.analytic_account_id.id or False
3985+ }
3986+
3987+ if st.currency.id <> company_currency_id:
3988+ amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
3989+ st.currency.id, amount, context=context)
3990+ val['amount_currency'] = -amount_cur
3991+
3992+ if st_line.account_id and st_line.account_id.currency_id and st_line.account_id.currency_id.id <> company_currency_id:
3993+ val['currency_id'] = st_line.account_id.currency_id.id
3994+ amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
3995+ st_line.account_id.currency_id.id, amount, context=context)
3996+ val['amount_currency'] = -amount_cur
3997+
3998+ move_line_id = account_move_line_obj.create(cr, uid, val, context=context)
3999+ torec.append(move_line_id)
4000+
4001+ # Fill the secondary amount/currency
4002+ # if currency is not the same than the company
4003+ amount_currency = False
4004+ currency_id = False
4005+ if st.currency.id <> company_currency_id:
4006+ amount_currency = st_line.amount
4007+ currency_id = st.currency.id
4008+ account_move_line_obj.create(cr, uid, {
4009+ 'name': st_line.name,
4010+ 'date': st_line.date,
4011+ 'ref': st_line.ref,
4012+ 'move_id': move_id,
4013+ 'partner_id': ((st_line.partner_id) and st_line.partner_id.id) or False,
4014+ 'account_id': account_id,
4015+ 'credit': ((amount < 0) and -amount) or 0.0,
4016+ 'debit': ((amount > 0) and amount) or 0.0,
4017+ 'statement_id': st.id,
4018+ 'journal_id': st.journal_id.id,
4019+ 'period_id': st.period_id.id,
4020+ 'amount_currency': amount_currency,
4021+ 'currency_id': currency_id,
4022+ }, context=context)
4023+
4024+ for line in account_move_line_obj.browse(cr, uid, [x.id for x in
4025+ account_move_obj.browse(cr, uid, move_id,
4026+ context=context).line_id],
4027+ context=context):
4028+ if line.state <> 'valid':
4029+ raise osv.except_osv(_('Error !'),
4030+ _('Journal Item "%s" is not valid') % line.name)
4031+
4032+ # Bank statements will not consider boolean on journal entry_posted
4033+ account_move_obj.post(cr, uid, [move_id], context=context)
4034+ return move_id
4035+
4036+ def get_next_st_line_number(self, cr, uid, st_number, st_line, context=None):
4037+ return st_number + '/' + str(st_line.sequence)
4038+
4039+ def balance_check(self, cr, uid, st_id, journal_type='bank', context=None):
4040+ st = self.browse(cr, uid, st_id, context=context)
4041+ if not (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001):
4042+ raise osv.except_osv(_('Error !'),
4043+ _('The statement balance is incorrect !\nThe expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
4044+ return True
4045+
4046+ def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
4047+ return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
4048+
4049+ def check_status_condition(self, cr, uid, state, journal_type='bank'):
4050+ return state in ('draft','open')
4051+
4052+ def button_confirm_bank(self, cr, uid, ids, context=None):
4053+ obj_seq = self.pool.get('ir.sequence')
4054+ if context is None:
4055+ context = {}
4056+
4057+ for st in self.browse(cr, uid, ids, context=context):
4058+ j_type = st.journal_id.type
4059+ company_currency_id = st.journal_id.company_id.currency_id.id
4060+ if not self.check_status_condition(cr, uid, st.state, journal_type=j_type):
4061+ continue
4062+
4063+ self.balance_check(cr, uid, st.id, journal_type=j_type, context=context)
4064+ if (not st.journal_id.default_credit_account_id) \
4065+ or (not st.journal_id.default_debit_account_id):
4066+ raise osv.except_osv(_('Configuration Error !'),
4067+ _('Please verify that an account is defined in the journal.'))
4068+
4069+ if not st.name == '/':
4070+ st_number = st.name
4071+ else:
4072+ if st.journal_id.sequence_id:
4073+ c = {'fiscalyear_id': st.period_id.fiscalyear_id.id}
4074+ st_number = obj_seq.next_by_id(cr, uid, st.journal_id.sequence_id.id, context=c)
4075+ else:
4076+ st_number = obj_seq.next_by_code(cr, uid, 'account.bank.statement')
4077+
4078+ for line in st.move_line_ids:
4079+ if line.state <> 'valid':
4080+ raise osv.except_osv(_('Error !'),
4081+ _('The account entries lines are not in valid state.'))
4082+ for st_line in st.line_ids:
4083+ if st_line.analytic_account_id:
4084+ if not st.journal_id.analytic_journal_id:
4085+ raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (st.journal_id.name,))
4086+ if not st_line.amount:
4087+ continue
4088+ st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context)
4089+ self.create_move_from_st_line(cr, uid, st_line.id, company_currency_id, st_line_number, context)
4090+
4091+ self.write(cr, uid, [st.id], {'name': st_number}, context=context)
4092+ self.log(cr, uid, st.id, _('Statement %s is confirmed, journal items are created.') % (st_number,))
4093+ return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
4094+
4095+ def button_cancel(self, cr, uid, ids, context=None):
4096+ done = []
4097+ account_move_obj = self.pool.get('account.move')
4098+ for st in self.browse(cr, uid, ids, context=context):
4099+ if st.state=='draft':
4100+ continue
4101+ ids = []
4102+ for line in st.line_ids:
4103+ ids += [x.id for x in line.move_ids]
4104+ account_move_obj.unlink(cr, uid, ids, context)
4105+ done.append(st.id)
4106+ return self.write(cr, uid, done, {'state':'draft'}, context=context)
4107+
4108+ def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
4109+ cr.execute('SELECT balance_end_real \
4110+ FROM account_bank_statement \
4111+ WHERE journal_id = %s AND NOT state = %s \
4112+ ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft'))
4113+ res = cr.fetchone()
4114+ balance_start = res and res[0] or 0.0
4115+ account_id = self.pool.get('account.journal').read(cr, uid, journal_id, ['default_debit_account_id'], context=context)['default_debit_account_id']
4116+ return {'value': {'balance_start': balance_start, 'account_id': account_id}}
4117+
4118+ def unlink(self, cr, uid, ids, context=None):
4119+ stat = self.read(cr, uid, ids, ['state'], context=context)
4120+ unlink_ids = []
4121+ for t in stat:
4122+ if t['state'] in ('draft'):
4123+ unlink_ids.append(t['id'])
4124+ else:
4125+ raise osv.except_osv(_('Invalid action !'), _('In order to delete a bank statement, you must first cancel it to delete related journal items.'))
4126+ osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
4127+ return True
4128+
4129+ def copy(self, cr, uid, id, default=None, context=None):
4130+ if default is None:
4131+ default = {}
4132+ if context is None:
4133+ context = {}
4134+ default = default.copy()
4135+ default['move_line_ids'] = []
4136+ return super(account_bank_statement, self).copy(cr, uid, id, default, context=context)
4137+
4138+account_bank_statement()
4139+
4140+class account_bank_statement_line(osv.osv):
4141+
4142+ def onchange_partner_id(self, cr, uid, ids, partner_id, context=None):
4143+ obj_partner = self.pool.get('res.partner')
4144+ if context is None:
4145+ context = {}
4146+ if not partner_id:
4147+ return {}
4148+ part = obj_partner.browse(cr, uid, partner_id, context=context)
4149+ if not part.supplier and not part.customer:
4150+ type = 'general'
4151+ elif part.supplier and part.customer:
4152+ type = 'general'
4153+ else:
4154+ if part.supplier == True:
4155+ type = 'supplier'
4156+ if part.customer == True:
4157+ type = 'customer'
4158+ res_type = self.onchange_type(cr, uid, ids, partner_id=partner_id, type=type, context=context)
4159+ if res_type['value'] and res_type['value'].get('account_id', False):
4160+ return {'value': {'type': type, 'account_id': res_type['value']['account_id']}}
4161+ return {'value': {'type': type}}
4162+
4163+ def onchange_type(self, cr, uid, line_id, partner_id, type, context=None):
4164+ res = {'value': {}}
4165+ obj_partner = self.pool.get('res.partner')
4166+ if context is None:
4167+ context = {}
4168+ if not partner_id:
4169+ return res
4170+ account_id = False
4171+ line = self.browse(cr, uid, line_id, context=context)
4172+ if not line or (line and not line[0].account_id):
4173+ part = obj_partner.browse(cr, uid, partner_id, context=context)
4174+ if type == 'supplier':
4175+ account_id = part.property_account_payable.id
4176+ else:
4177+ account_id = part.property_account_receivable.id
4178+ res['value']['account_id'] = account_id
4179+ return res
4180+
4181+ _order = "statement_id desc, sequence"
4182+ _name = "account.bank.statement.line"
4183+ _description = "Bank Statement Line"
4184+ _columns = {
4185+ 'name': fields.char('Communication', size=64, required=True),
4186+ 'date': fields.date('Date', required=True),
4187+ 'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
4188+ 'type': fields.selection([
4189+ ('supplier','Supplier'),
4190+ ('customer','Customer'),
4191+ ('general','General')
4192+ ], 'Type', required=True),
4193+ 'partner_id': fields.many2one('res.partner', 'Partner'),
4194+ 'account_id': fields.many2one('account.account','Account',
4195+ required=True),
4196+ 'statement_id': fields.many2one('account.bank.statement', 'Statement',
4197+ select=True, required=True, ondelete='cascade'),
4198+ 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'),
4199+ 'move_ids': fields.many2many('account.move',
4200+ 'account_bank_statement_line_move_rel', 'statement_line_id','move_id',
4201+ 'Moves'),
4202+ 'ref': fields.char('Reference', size=32),
4203+ 'note': fields.text('Notes'),
4204+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bank statement lines."),
4205+ 'company_id': fields.related('statement_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
4206+ }
4207+ _defaults = {
4208+ 'name': lambda self,cr,uid,context={}: self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement.line'),
4209+ 'date': lambda self,cr,uid,context={}: context.get('date', time.strftime('%Y-%m-%d')),
4210+ 'type': 'general',
4211+ }
4212+
4213+account_bank_statement_line()
4214+
4215+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4216
4217=== added file 'account/account_bank_view.xml'
4218--- account/account_bank_view.xml 1970-01-01 00:00:00 +0000
4219+++ account/account_bank_view.xml 2011-10-06 16:09:39 +0000
4220@@ -0,0 +1,48 @@
4221+<?xml version="1.0" encoding="utf-8"?>
4222+<openerp>
4223+<data>
4224+
4225+ <!--
4226+ Bank Accounts
4227+ -->
4228+
4229+ <record id="view_partner_bank_form_inherit" model="ir.ui.view">
4230+ <field name="name">Partner Bank Accounts - Journal</field>
4231+ <field name="model">res.partner.bank</field>
4232+ <field name="type">form</field>
4233+ <field name="inherit_id" ref="base.view_partner_bank_form"/>
4234+ <field name="arch" type="xml">
4235+ <group name="bank" position="after">
4236+ <group name="accounting" col="2" colspan="2" attrs="{'invisible': [('company_id','=', False)]}" groups="base.group_extended">
4237+ <separator string="Accounting Information" colspan="2"/>
4238+ <field name="journal_id"/>
4239+ </group>
4240+ </group>
4241+ </field>
4242+ </record>
4243+
4244+
4245+ <record id="action_bank_tree" model="ir.actions.act_window">
4246+ <field name="name">Setup your Bank Accounts</field>
4247+ <field name="res_model">res.partner.bank</field>
4248+ <field name="view_type">form</field>
4249+ <field name="view_mode">tree,form</field>
4250+ <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}"/>
4251+ <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>
4252+ </record>
4253+ <menuitem
4254+ sequence="0"
4255+ parent="account.account_account_menu"
4256+ id="menu_action_bank_tree"
4257+ action="action_bank_tree"/>
4258+
4259+
4260+ <record id="account_configuration_bank_todo" model="ir.actions.todo">
4261+ <field name="action_id" ref="action_bank_tree"/>
4262+ <field name="category_id" ref="category_accounting_configuration"/>
4263+ <field name="sequence">4</field>
4264+ </record>
4265+
4266+
4267+</data>
4268+</openerp>
4269
4270=== added file 'account/account_cash_statement.py'
4271--- account/account_cash_statement.py 1970-01-01 00:00:00 +0000
4272+++ account/account_cash_statement.py 2011-10-06 16:09:39 +0000
4273@@ -0,0 +1,345 @@
4274+# encoding: utf-8
4275+##############################################################################
4276+#
4277+# OpenERP, Open Source Management Solution
4278+# Copyright (C) 2004-2008 PC Solutions (<http://pcsol.be>). All Rights Reserved
4279+# $Id$
4280+#
4281+# This program is free software: you can redistribute it and/or modify
4282+# it under the terms of the GNU General Public License as published by
4283+# the Free Software Foundation, either version 3 of the License, or
4284+# (at your option) any later version.
4285+#
4286+# This program is distributed in the hope that it will be useful,
4287+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4288+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4289+# GNU General Public License for more details.
4290+#
4291+# You should have received a copy of the GNU General Public License
4292+# along with this program. If not, see <http://www.gnu.org/licenses/>.
4293+#
4294+##############################################################################
4295+
4296+import time
4297+
4298+from osv import osv, fields
4299+from tools.translate import _
4300+import decimal_precision as dp
4301+
4302+class account_cashbox_line(osv.osv):
4303+
4304+ """ Cash Box Details """
4305+
4306+ _name = 'account.cashbox.line'
4307+ _description = 'CashBox Line'
4308+ _rec_name = 'number'
4309+
4310+ def _sub_total(self, cr, uid, ids, name, arg, context=None):
4311+
4312+ """ Calculates Sub total
4313+ @param name: Names of fields.
4314+ @param arg: User defined arguments
4315+ @return: Dictionary of values.
4316+ """
4317+ res = {}
4318+ for obj in self.browse(cr, uid, ids, context=context):
4319+ res[obj.id] = obj.pieces * obj.number
4320+ return res
4321+
4322+ def on_change_sub(self, cr, uid, ids, pieces, number, *a):
4323+
4324+ """ Calculates Sub total on change of number
4325+ @param pieces: Names of fields.
4326+ @param number:
4327+ """
4328+ sub = pieces * number
4329+ return {'value': {'subtotal': sub or 0.0}}
4330+
4331+ _columns = {
4332+ 'pieces': fields.float('Values', digits_compute=dp.get_precision('Account')),
4333+ 'number': fields.integer('Number'),
4334+ 'subtotal': fields.function(_sub_total, string='Sub Total', type='float', digits_compute=dp.get_precision('Account')),
4335+ 'starting_id': fields.many2one('account.bank.statement', ondelete='cascade'),
4336+ 'ending_id': fields.many2one('account.bank.statement', ondelete='cascade'),
4337+ }
4338+
4339+account_cashbox_line()
4340+
4341+class account_cash_statement(osv.osv):
4342+
4343+ _inherit = 'account.bank.statement'
4344+
4345+ def _get_starting_balance(self, cr, uid, ids, context=None):
4346+
4347+ """ Find starting balance
4348+ @param name: Names of fields.
4349+ @param arg: User defined arguments
4350+ @return: Dictionary of values.
4351+ """
4352+ res = {}
4353+ for statement in self.browse(cr, uid, ids, context=context):
4354+ amount_total = 0.0
4355+
4356+ if statement.journal_id.type not in('cash'):
4357+ continue
4358+
4359+ for line in statement.starting_details_ids:
4360+ amount_total+= line.pieces * line.number
4361+ res[statement.id] = {
4362+ 'balance_start': amount_total
4363+ }
4364+ return res
4365+
4366+ def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
4367+ """ Find ending balance "
4368+ @param name: Names of fields.
4369+ @param arg: User defined arguments
4370+ @return: Dictionary of values.
4371+ """
4372+ res = {}
4373+ for statement in self.browse(cr, uid, ids, context=context):
4374+ amount_total = 0.0
4375+ for line in statement.ending_details_ids:
4376+ amount_total += line.pieces * line.number
4377+ res[statement.id] = amount_total
4378+ return res
4379+
4380+ def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
4381+
4382+ """ Find encoding total of statements "
4383+ @param name: Names of fields.
4384+ @param arg: User defined arguments
4385+ @return: Dictionary of values.
4386+ """
4387+ res2 = {}
4388+ for statement in self.browse(cr, uid, ids, context=context):
4389+ encoding_total=0.0
4390+ for line in statement.line_ids:
4391+ encoding_total += line.amount
4392+ res2[statement.id] = encoding_total
4393+ return res2
4394+
4395+ def _get_company(self, cr, uid, context=None):
4396+ user_pool = self.pool.get('res.users')
4397+ company_pool = self.pool.get('res.company')
4398+ user = user_pool.browse(cr, uid, uid, context=context)
4399+ company_id = user.company_id
4400+ if not company_id:
4401+ company_id = company_pool.search(cr, uid, [])
4402+ return company_id and company_id[0] or False
4403+
4404+ def _get_cash_open_box_lines(self, cr, uid, context=None):
4405+ res = []
4406+ curr = [1, 2, 5, 10, 20, 50, 100, 500]
4407+ for rs in curr:
4408+ dct = {
4409+ 'pieces': rs,
4410+ 'number': 0
4411+ }
4412+ res.append(dct)
4413+ journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')], context=context)
4414+ if journal_ids:
4415+ results = self.search(cr, uid, [('journal_id', 'in', journal_ids),('state', '=', 'confirm')], context=context)
4416+ if results:
4417+ cash_st = self.browse(cr, uid, results, context=context)[0]
4418+ for cash_line in cash_st.ending_details_ids:
4419+ for r in res:
4420+ if cash_line.pieces == r['pieces']:
4421+ r['number'] = cash_line.number
4422+ return res
4423+
4424+ def _get_default_cash_close_box_lines(self, cr, uid, context=None):
4425+ res = []
4426+ curr = [1, 2, 5, 10, 20, 50, 100, 500]
4427+ for rs in curr:
4428+ dct = {
4429+ 'pieces': rs,
4430+ 'number': 0
4431+ }
4432+ res.append(dct)
4433+ return res
4434+
4435+ def _get_cash_close_box_lines(self, cr, uid, context=None):
4436+ res = []
4437+ curr = [1, 2, 5, 10, 20, 50, 100, 500]
4438+ for rs in curr:
4439+ dct = {
4440+ 'pieces': rs,
4441+ 'number': 0
4442+ }
4443+ res.append((0, 0, dct))
4444+ return res
4445+
4446+ def _get_cash_open_close_box_lines(self, cr, uid, context=None):
4447+ res = {}
4448+ start_l = []
4449+ end_l = []
4450+ starting_details = self._get_cash_open_box_lines(cr, uid, context=context)
4451+ ending_details = self._get_default_cash_close_box_lines(cr, uid, context)
4452+ for start in starting_details:
4453+ start_l.append((0, 0, start))
4454+ for end in ending_details:
4455+ end_l.append((0, 0, end))
4456+ res['start'] = start_l
4457+ res['end'] = end_l
4458+ return res
4459+
4460+ def _get_statement(self, cr, uid, ids, context=None):
4461+ result = {}
4462+ for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
4463+ result[line.statement_id.id] = True
4464+ return result.keys()
4465+
4466+ _columns = {
4467+ 'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Cash Transaction", help="Total cash transactions",
4468+ store = {
4469+ 'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
4470+ 'account.bank.statement.line': (_get_statement, ['amount'], 10),
4471+ }),
4472+ 'closing_date': fields.datetime("Closed On"),
4473+ 'balance_end_cash': fields.function(_balance_end_cash, store=True, string='Closing Balance', help="Closing balance based on cashBox"),
4474+ 'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'),
4475+ 'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'),
4476+ 'user_id': fields.many2one('res.users', 'Responsible', required=False),
4477+ }
4478+ _defaults = {
4479+ 'state': 'draft',
4480+ 'date': lambda self,cr,uid,context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")),
4481+ 'user_id': lambda self, cr, uid, context=None: uid,
4482+ 'starting_details_ids': _get_cash_open_box_lines,
4483+ 'ending_details_ids': _get_default_cash_close_box_lines
4484+ }
4485+
4486+ def create(self, cr, uid, vals, context=None):
4487+ if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash':
4488+ open_close = self._get_cash_open_close_box_lines(cr, uid, context)
4489+ if vals.get('starting_details_ids', False):
4490+ for start in vals.get('starting_details_ids'):
4491+ dict_val = start[2]
4492+ for end in open_close['end']:
4493+ if end[2]['pieces'] == dict_val['pieces']:
4494+ end[2]['number'] += dict_val['number']
4495+ vals.update({
4496+# 'ending_details_ids': open_close['start'],
4497+ 'starting_details_ids': open_close['end']
4498+ })
4499+ else:
4500+ vals.update({
4501+ 'ending_details_ids': False,
4502+ 'starting_details_ids': False
4503+ })
4504+ res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
4505+ self.write(cr, uid, [res_id], {})
4506+ return res_id
4507+
4508+ def write(self, cr, uid, ids, vals, context=None):
4509+ """
4510+ Update redord(s) comes in {ids}, with new value comes as {vals}
4511+ return True on success, False otherwise
4512+
4513+ @param cr: cursor to database
4514+ @param user: id of current user
4515+ @param ids: list of record ids to be update
4516+ @param vals: dict of new values to be set
4517+ @param context: context arguments, like lang, time zone
4518+
4519+ @return: True on success, False otherwise
4520+ """
4521+
4522+ super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
4523+ res = self._get_starting_balance(cr, uid, ids)
4524+ for rs in res:
4525+ super(account_cash_statement, self).write(cr, uid, [rs], res.get(rs))
4526+ return True
4527+
4528+ def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
4529+ """ Changes balance start and starting details if journal_id changes"
4530+ @param statement_id: Changed statement_id
4531+ @param journal_id: Changed journal_id
4532+ @return: Dictionary of changed values
4533+ """
4534+ res = {}
4535+ balance_start = 0.0
4536+ if not journal_id:
4537+ res.update({
4538+ 'balance_start': balance_start
4539+ })
4540+ return res
4541+ return super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
4542+
4543+ def _equal_balance(self, cr, uid, cash_id, context=None):
4544+ statement = self.browse(cr, uid, cash_id, context=context)
4545+ self.write(cr, uid, [cash_id], {'balance_end_real': statement.balance_end})
4546+ statement.balance_end_real = statement.balance_end
4547+ if statement.balance_end != statement.balance_end_cash:
4548+ return False
4549+ return True
4550+
4551+ def _user_allow(self, cr, uid, statement_id, context=None):
4552+ return True
4553+
4554+ def button_open(self, cr, uid, ids, context=None):
4555+ """ Changes statement state to Running.
4556+ @return: True
4557+ """
4558+ obj_seq = self.pool.get('ir.sequence')
4559+ if context is None:
4560+ context = {}
4561+ statement_pool = self.pool.get('account.bank.statement')
4562+ for statement in statement_pool.browse(cr, uid, ids, context=context):
4563+ vals = {}
4564+ if not self._user_allow(cr, uid, statement.id, context=context):
4565+ raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name)))
4566+
4567+ if statement.name and statement.name == '/':
4568+ if statement.journal_id.sequence_id:
4569+ c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
4570+ st_number = obj_seq.next_by_id(cr, uid, statement.journal_id.sequence_id.id, context=c)
4571+ else:
4572+ st_number = obj_seq.next_by_code(cr, uid, 'account.cash.statement')
4573+ vals.update({
4574+ 'name': st_number
4575+ })
4576+
4577+ vals.update({
4578+ 'state': 'open',
4579+ })
4580+ self.write(cr, uid, [statement.id], vals, context=context)
4581+ return True
4582+
4583+ def balance_check(self, cr, uid, cash_id, journal_type='bank', context=None):
4584+ if journal_type == 'bank':
4585+ return super(account_cash_statement, self).balance_check(cr, uid, cash_id, journal_type, context)
4586+ if not self._equal_balance(cr, uid, cash_id, context):
4587+ raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance !'))
4588+ return True
4589+
4590+ def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
4591+ if journal_type == 'bank':
4592+ return super(account_cash_statement, self).statement_close(cr, uid, ids, journal_type, context)
4593+ vals = {
4594+ 'state':'confirm',
4595+ 'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")
4596+ }
4597+ return self.write(cr, uid, ids, vals, context=context)
4598+
4599+ def check_status_condition(self, cr, uid, state, journal_type='bank'):
4600+ if journal_type == 'bank':
4601+ return super(account_cash_statement, self).check_status_condition(cr, uid, state, journal_type)
4602+ return state=='open'
4603+
4604+ def button_confirm_cash(self, cr, uid, ids, context=None):
4605+ super(account_cash_statement, self).button_confirm_bank(cr, uid, ids, context=context)
4606+ return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context)
4607+
4608+ def button_cancel(self, cr, uid, ids, context=None):
4609+ cash_box_line_pool = self.pool.get('account.cashbox.line')
4610+ super(account_cash_statement, self).button_cancel(cr, uid, ids, context=context)
4611+ for st in self.browse(cr, uid, ids, context):
4612+ for end in st.ending_details_ids:
4613+ cash_box_line_pool.write(cr, uid, [end.id], {'number': 0})
4614+ return True
4615+
4616+account_cash_statement()
4617+
4618+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4619
4620=== added file 'account/account_end_fy.xml'
4621--- account/account_end_fy.xml 1970-01-01 00:00:00 +0000
4622+++ account/account_end_fy.xml 2011-10-06 16:09:39 +0000
4623@@ -0,0 +1,20 @@
4624+<?xml version="1.0" encoding="utf-8"?>
4625+<openerp>
4626+ <data>
4627+
4628+ <record id="action_account_period_tree" model="ir.actions.act_window">
4629+ <field name="name">Close a Period</field>
4630+ <field name="res_model">account.period</field>
4631+ <field name="view_type">form</field>
4632+ <field name="view_id" ref="view_account_period_tree"/>
4633+ <field name="context">{'search_default_draft': 1}</field>
4634+ <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>
4635+ </record>
4636+ <menuitem
4637+ action="action_account_period_tree"
4638+ id="menu_action_account_period_close_tree"
4639+ parent="account.menu_account_end_year_treatments"
4640+ sequence="0" groups="base.group_extended"/>
4641+
4642+ </data>
4643+</openerp>
4644
4645=== added file 'account/account_installer.xml'
4646--- account/account_installer.xml 1970-01-01 00:00:00 +0000
4647+++ account/account_installer.xml 2011-10-06 16:09:39 +0000
4648@@ -0,0 +1,112 @@
4649+<openerp>
4650+ <data>
4651+ <record id="view_account_configuration_installer" model="ir.ui.view">
4652+ <field name="name">account.installer.form</field>
4653+ <field name="model">account.installer</field>
4654+ <field name="type">form</field>
4655+ <field name="inherit_id" ref="base.res_config_installer"/>
4656+ <field name="arch" type="xml">
4657+ <data>
4658+ <form position="attributes">
4659+ <attribute name="string">Accounting Application Configuration</attribute>
4660+ </form>
4661+ <separator string="title" position="attributes">
4662+ <attribute name="string">Configure Your Chart of Accounts</attribute>
4663+ </separator>
4664+ <xpath expr="//label[@string='description']" position="attributes">
4665+ <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>
4666+ </xpath>
4667+ <xpath expr="//button[@string='Install Modules']" position="attributes">
4668+ <attribute name="string">Configure</attribute>
4669+ </xpath>
4670+ <xpath expr="//separator[@string=&quot;vsep&quot;]" position="attributes">
4671+ <attribute name="rowspan">23</attribute>
4672+ <attribute name="string"/>
4673+ </xpath>
4674+ <group colspan="8" position="inside">
4675+ <group colspan="4" width="600">
4676+ <field name="charts"/>
4677+ <group colspan="4" groups="account.group_account_user">
4678+ <separator col="4" colspan="4" string="Configure Fiscal Year"/>
4679+ <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 -->
4680+ <field name="date_start" on_change="on_change_start_date(date_start)"/>
4681+ <field name="date_stop"/>
4682+ <field name="period" colspan="4"/>
4683+ </group>
4684+ <group colspan="4" attrs="{'invisible':[('charts','!=','configurable')]}">
4685+ <field name="sale_tax" on_change="on_change_tax(sale_tax)" attrs="{'required':[('charts','=','configurable')]}"/>
4686+ <field name="purchase_tax" groups="base.group_extended"/>
4687+ </group>
4688+ </group>
4689+ </group>
4690+ </data>
4691+ </field>
4692+ </record>
4693+
4694+ <record id="action_account_configuration_installer" model="ir.actions.act_window">
4695+ <field name="name">Install your Chart of Accounts</field>
4696+ <field name="type">ir.actions.act_window</field>
4697+ <field name="res_model">account.installer</field>
4698+ <field name="view_id" ref="view_account_configuration_installer"/>
4699+ <field name="view_type">form</field>
4700+ <field name="view_mode">form</field>
4701+ <field name="target">new</field>
4702+ </record>
4703+
4704+ <record id="category_accounting_configuration" model="ir.actions.todo.category">
4705+ <field name="name">Accounting</field>
4706+ <field name="sequence">5</field>
4707+ </record>
4708+
4709+ <record id="account_configuration_installer_todo" model="ir.actions.todo">
4710+ <field name="action_id" ref="action_account_configuration_installer"/>
4711+ <field name="category_id" ref="category_accounting_configuration"/>
4712+ <field name="sequence">3</field>
4713+ <field name="type">automatic</field>
4714+ </record>
4715+
4716+ <record id="action_view_financial_accounts_installer" model="ir.actions.act_window">
4717+ <field name="name">Review your Financial Accounts</field>
4718+ <field name="type">ir.actions.act_window</field>
4719+ <field name="res_model">account.account</field>
4720+ <field name="view_type">form</field>
4721+ <field name="view_mode">tree,form</field>
4722+ <field name="context">{'config_invisible': False}</field>
4723+ </record>
4724+
4725+ <record id="view_financial_accounts_todo" model="ir.actions.todo">
4726+ <field name="action_id" ref="action_view_financial_accounts_installer" />
4727+ <field name="category_id" ref="category_accounting_configuration" />
4728+ <field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
4729+ </record>
4730+
4731+ <record id="action_review_financial_journals_installer" model="ir.actions.act_window">
4732+ <field name="name">Review your Financial Journals</field>
4733+ <field name="type">ir.actions.act_window</field>
4734+ <field name="res_model">account.journal</field>
4735+ <field name="view_type">form</field>
4736+ <field name="view_mode">tree,form</field>
4737+ <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>
4738+ </record>
4739+
4740+ <record id="review_financial_journals_todo" model="ir.actions.todo">
4741+ <field name="action_id" ref="action_review_financial_journals_installer" />
4742+ <field name="category_id" ref="category_accounting_configuration" />
4743+ <field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
4744+ </record>
4745+ <record id="action_review_payment_terms_installer" model="ir.actions.act_window">
4746+ <field name="name">Review your Payment Terms</field>
4747+ <field name="type">ir.actions.act_window</field>
4748+ <field name="res_model">account.payment.term</field>
4749+ <field name="view_type">form</field>
4750+ <field name="view_mode">tree,form</field>
4751+ <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>
4752+ </record>
4753+
4754+ <record id="review_payment_terms_todo" model="ir.actions.todo">
4755+ <field name="action_id" ref="action_review_payment_terms_installer" />
4756+ <field name="category_id" ref="category_accounting_configuration" />
4757+ <field name="groups_id" eval="[(6, 0, [ref('account.group_account_user')])]" />
4758+ </record>
4759+ </data>
4760+</openerp>
4761
4762=== added file 'account/account_invoice.py'
4763--- account/account_invoice.py 1970-01-01 00:00:00 +0000
4764+++ account/account_invoice.py 2011-10-06 16:09:39 +0000
4765@@ -0,0 +1,1641 @@
4766+# -*- coding: utf-8 -*-
4767+##############################################################################
4768+#
4769+# OpenERP, Open Source Management Solution
4770+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
4771+#
4772+# This program is free software: you can redistribute it and/or modify
4773+# it under the terms of the GNU Affero General Public License as
4774+# published by the Free Software Foundation, either version 3 of the
4775+# License, or (at your option) any later version.
4776+#
4777+# This program is distributed in the hope that it will be useful,
4778+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4779+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4780+# GNU Affero General Public License for more details.
4781+#
4782+# You should have received a copy of the GNU Affero General Public License
4783+# along with this program. If not, see <http://www.gnu.org/licenses/>.
4784+#
4785+##############################################################################
4786+
4787+import time
4788+from lxml import etree
4789+import decimal_precision as dp
4790+
4791+import netsvc
4792+import pooler
4793+from osv import fields, osv, orm
4794+from tools.translate import _
4795+
4796+class account_invoice(osv.osv):
4797+ def _amount_all(self, cr, uid, ids, name, args, context=None):
4798+ res = {}
4799+ for invoice in self.browse(cr, uid, ids, context=context):
4800+ res[invoice.id] = {
4801+ 'amount_untaxed': 0.0,
4802+ 'amount_tax': 0.0,
4803+ 'amount_total': 0.0
4804+ }
4805+ for line in invoice.invoice_line:
4806+ res[invoice.id]['amount_untaxed'] += line.price_subtotal
4807+ for line in invoice.tax_line:
4808+ res[invoice.id]['amount_tax'] += line.amount
4809+ res[invoice.id]['amount_total'] = res[invoice.id]['amount_tax'] + res[invoice.id]['amount_untaxed']
4810+ return res
4811+
4812+ def _get_journal(self, cr, uid, context=None):
4813+ if context is None:
4814+ context = {}
4815+ type_inv = context.get('type', 'out_invoice')
4816+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
4817+ company_id = context.get('company_id', user.company_id.id)
4818+ type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale_refund', 'in_refund': 'purchase_refund'}
4819+ journal_obj = self.pool.get('account.journal')
4820+ res = journal_obj.search(cr, uid, [('type', '=', type2journal.get(type_inv, 'sale')),
4821+ ('company_id', '=', company_id)],
4822+ limit=1)
4823+ return res and res[0] or False
4824+
4825+ def _get_currency(self, cr, uid, context=None):
4826+ user = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, [uid], context=context)[0]
4827+ if user.company_id:
4828+ return user.company_id.currency_id.id
4829+ return pooler.get_pool(cr.dbname).get('res.currency').search(cr, uid, [('rate','=', 1.0)])[0]
4830+
4831+ def _get_journal_analytic(self, cr, uid, type_inv, context=None):
4832+ type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale', 'in_refund': 'purchase'}
4833+ tt = type2journal.get(type_inv, 'sale')
4834+ result = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=',tt)], context=context)
4835+ if not result:
4836+ raise osv.except_osv(_('No Analytic Journal !'),_("You must define an analytic journal of type '%s' !") % (tt,))
4837+ return result[0]
4838+
4839+ def _get_type(self, cr, uid, context=None):
4840+ if context is None:
4841+ context = {}
4842+ return context.get('type', 'out_invoice')
4843+
4844+ def _reconciled(self, cr, uid, ids, name, args, context=None):
4845+ res = {}
4846+ for id in ids:
4847+ res[id] = self.test_paid(cr, uid, [id])
4848+ return res
4849+
4850+ def _get_reference_type(self, cr, uid, context=None):
4851+ return [('none', _('Free Reference'))]
4852+
4853+ def _amount_residual(self, cr, uid, ids, name, args, context=None):
4854+ result = {}
4855+ for invoice in self.browse(cr, uid, ids, context=context):
4856+ result[invoice.id] = 0.0
4857+ if invoice.move_id:
4858+ for m in invoice.move_id.line_id:
4859+ if m.account_id.type in ('receivable','payable'):
4860+ result[invoice.id] += m.amount_residual_currency
4861+ return result
4862+
4863+ # Give Journal Items related to the payment reconciled to this invoice
4864+ # Return ids of partial and total payments related to the selected invoices
4865+ def _get_lines(self, cr, uid, ids, name, arg, context=None):
4866+ res = {}
4867+ for invoice in self.browse(cr, uid, ids, context=context):
4868+ id = invoice.id
4869+ res[id] = []
4870+ if not invoice.move_id:
4871+ continue
4872+ data_lines = [x for x in invoice.move_id.line_id if x.account_id.id == invoice.account_id.id]
4873+ partial_ids = []
4874+ for line in data_lines:
4875+ ids_line = []
4876+ if line.reconcile_id:
4877+ ids_line = line.reconcile_id.line_id
4878+ elif line.reconcile_partial_id:
4879+ ids_line = line.reconcile_partial_id.line_partial_ids
4880+ l = map(lambda x: x.id, ids_line)
4881+ partial_ids.append(line.id)
4882+ res[id] =[x for x in l if x <> line.id and x not in partial_ids]
4883+ return res
4884+
4885+ def _get_invoice_line(self, cr, uid, ids, context=None):
4886+ result = {}
4887+ for line in self.pool.get('account.invoice.line').browse(cr, uid, ids, context=context):
4888+ result[line.invoice_id.id] = True
4889+ return result.keys()
4890+
4891+ def _get_invoice_tax(self, cr, uid, ids, context=None):
4892+ result = {}
4893+ for tax in self.pool.get('account.invoice.tax').browse(cr, uid, ids, context=context):
4894+ result[tax.invoice_id.id] = True
4895+ return result.keys()
4896+
4897+ def _compute_lines(self, cr, uid, ids, name, args, context=None):
4898+ result = {}
4899+ for invoice in self.browse(cr, uid, ids, context=context):
4900+ src = []
4901+ lines = []
4902+ if invoice.move_id:
4903+ for m in invoice.move_id.line_id:
4904+ temp_lines = []
4905+ if m.reconcile_id:
4906+ temp_lines = map(lambda x: x.id, m.reconcile_id.line_id)
4907+ elif m.reconcile_partial_id:
4908+ temp_lines = map(lambda x: x.id, m.reconcile_partial_id.line_partial_ids)
4909+ lines += [x for x in temp_lines if x not in lines]
4910+ src.append(m.id)
4911+
4912+ lines = filter(lambda x: x not in src, lines)
4913+ result[invoice.id] = lines
4914+ return result
4915+
4916+ def _get_invoice_from_line(self, cr, uid, ids, context=None):
4917+ move = {}
4918+ for line in self.pool.get('account.move.line').browse(cr, uid, ids, context=context):
4919+ if line.reconcile_partial_id:
4920+ for line2 in line.reconcile_partial_id.line_partial_ids:
4921+ move[line2.move_id.id] = True
4922+ if line.reconcile_id:
4923+ for line2 in line.reconcile_id.line_id:
4924+ move[line2.move_id.id] = True
4925+ invoice_ids = []
4926+ if move:
4927+ invoice_ids = self.pool.get('account.invoice').search(cr, uid, [('move_id','in',move.keys())], context=context)
4928+ return invoice_ids
4929+
4930+ def _get_invoice_from_reconcile(self, cr, uid, ids, context=None):
4931+ move = {}
4932+ for r in self.pool.get('account.move.reconcile').browse(cr, uid, ids, context=context):
4933+ for line in r.line_partial_ids:
4934+ move[line.move_id.id] = True
4935+ for line in r.line_id:
4936+ move[line.move_id.id] = True
4937+
4938+ invoice_ids = []
4939+ if move:
4940+ invoice_ids = self.pool.get('account.invoice').search(cr, uid, [('move_id','in',move.keys())], context=context)
4941+ return invoice_ids
4942+
4943+ _name = "account.invoice"
4944+ _description = 'Invoice'
4945+ _order = "id desc"
4946+
4947+ _columns = {
4948+ 'name': fields.char('Description', size=64, select=True, readonly=True, states={'draft':[('readonly',False)]}),
4949+ 'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}),
4950+ 'type': fields.selection([
4951+ ('out_invoice','Customer Invoice'),
4952+ ('in_invoice','Supplier Invoice'),
4953+ ('out_refund','Customer Refund'),
4954+ ('in_refund','Supplier Refund'),
4955+ ],'Type', readonly=True, select=True, change_default=True),
4956+
4957+ 'number': fields.related('move_id','name', type='char', readonly=True, size=64, relation='account.move', store=True, string='Number'),
4958+ 'internal_number': fields.char('Invoice Number', size=32, readonly=True, help="Unique number of the invoice, computed automatically when the invoice is created."),
4959+ 'reference': fields.char('Invoice Reference', size=64, help="The partner reference of this invoice."),
4960+ 'reference_type': fields.selection(_get_reference_type, 'Reference Type',
4961+ required=True, readonly=True, states={'draft':[('readonly',False)]}),
4962+ 'comment': fields.text('Additional Information'),
4963+
4964+ 'state': fields.selection([
4965+ ('draft','Draft'),
4966+ ('proforma','Pro-forma'),
4967+ ('proforma2','Pro-forma'),
4968+ ('open','Open'),
4969+ ('paid','Paid'),
4970+ ('cancel','Cancelled')
4971+ ],'State', select=True, readonly=True,
4972+ help=' * The \'Draft\' state is used when a user is encoding a new and unconfirmed Invoice. \
4973+ \n* The \'Pro-forma\' when invoice is in Pro-forma state,invoice does not have an invoice number. \
4974+ \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. \
4975+ \n* The \'Paid\' state is set automatically when invoice is paid.\
4976+ \n* The \'Cancelled\' state is used when user cancel invoice.'),
4977+ '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"),
4978+ 'date_due': fields.date('Due Date', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]}, select=True,
4979+ help="If you use payment terms, the due date will be computed automatically at the generation "\
4980+ "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."),
4981+ 'partner_id': fields.many2one('res.partner', 'Partner', change_default=True, readonly=True, required=True, states={'draft':[('readonly',False)]}),
4982+ 'address_contact_id': fields.many2one('res.partner.address', 'Contact Address', readonly=True, states={'draft':[('readonly',False)]}),
4983+ 'address_invoice_id': fields.many2one('res.partner.address', 'Invoice Address', readonly=True, required=True, states={'draft':[('readonly',False)]}),
4984+ 'payment_term': fields.many2one('account.payment.term', 'Payment Term',readonly=True, states={'draft':[('readonly',False)]},
4985+ help="If you use payment terms, the due date will be computed automatically at the generation "\
4986+ "of accounting entries. If you keep the payment term and the due date empty, it means direct payment. "\
4987+ "The payment term may compute several due dates, for example 50% now, 50% in one month."),
4988+ '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)]}),
4989+
4990+ 'account_id': fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="The partner account used for this invoice."),
4991+ 'invoice_line': fields.one2many('account.invoice.line', 'invoice_id', 'Invoice Lines', readonly=True, states={'draft':[('readonly',False)]}),
4992+ 'tax_line': fields.one2many('account.invoice.tax', 'invoice_id', 'Tax Lines', readonly=True, states={'draft':[('readonly',False)]}),
4993+
4994+ 'move_id': fields.many2one('account.move', 'Journal Entry', readonly=True, select=1, ondelete='restrict', help="Link to the automatically generated Journal Items."),
4995+ 'amount_untaxed': fields.function(_amount_all, digits_compute=dp.get_precision('Account'), string='Untaxed',
4996+ store={
4997+ 'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20),
4998+ 'account.invoice.tax': (_get_invoice_tax, None, 20),
4999+ 'account.invoice.line': (_get_invoice_line, ['price_unit','invoice_line_tax_id','quantity','discount','invoice_id'], 20),
5000+ },
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches