Skip to content
Permalink
Browse files

[MERGE] forward port branch saas-12.3 up to 120359b

  • Loading branch information...
KangOl committed Apr 12, 2019
2 parents db97bb7 + 120359b commit 0a09a4d8a819ef06db47e798f0465e500004e4c1
Showing with 5,060 additions and 1,946 deletions.
  1. +1 −1 addons/account/__manifest__.py
  2. +10 −0 addons/account/i18n/account.pot
  3. +1 −1 addons/account/models/__init__.py
  4. +7 −8 addons/account/models/account.py
  5. +7 −3 addons/account/models/account_bank_statement.py
  6. +24 −10 addons/account/models/account_invoice.py
  7. +19 −3 addons/account/models/account_move.py
  8. +244 −295 addons/account/models/account_payment.py
  9. +11 −0 addons/account/models/reconciliation_widget.py
  10. +26 −0 addons/account/models/res_users.py
  11. +10 −12 addons/account/security/account_security.xml
  12. +1 −2 addons/account/static/src/js/bills_tree_upload.js
  13. +2 −2 addons/account/static/src/js/reconciliation/reconciliation_action.js
  14. +4 −1 addons/account/static/src/js/reconciliation/reconciliation_renderer.js
  15. +2 −2 addons/account/static/src/xml/account_reconciliation.xml
  16. +1 −0 addons/account/static/tests/reconciliation_tests.js
  17. +42 −165 addons/account/tests/test_payment.py
  18. +124 −1 addons/account/tests/test_reconciliation.py
  19. +7 −6 addons/account/views/account_invoice_view.xml
  20. +0 −3 addons/account/views/account_journal_dashboard_view.xml
  21. +2 −1 addons/account/views/account_move_views.xml
  22. +74 −151 addons/account/views/account_payment_view.xml
  23. +2 −2 addons/account/views/account_view.xml
  24. +16 −19 addons/account/views/report_invoice.xml
  25. +1 −1 addons/account/views/report_payment_receipt_templates.xml
  26. +1 −0 addons/account/wizard/__init__.py
  27. +12 −6 addons/account/{models/account_invoice_import_wizard.py → wizard/account_invoice_import.py}
  28. +1 −6 ...s/account/{views/account_invoice_import_wizard_view.xml → wizard/account_invoice_import_view.xml}
  29. +16 −28 addons/account_check_printing/models/account_payment.py
  30. +1 −0 addons/account_check_printing/tests/__init__.py
  31. +22 −15 addons/account_check_printing/tests/test_print_check.py
  32. +0 −27 addons/account_check_printing/views/account_payment_views.xml
  33. +1 −1 addons/account_facturx/__manifest__.py
  34. +115 −53 addons/account_facturx/models/account_invoice.py
  35. +1 −1 addons/account_payment/views/account_portal_templates.xml
  36. +2 −2 addons/base_address_city/models/res_partner.py
  37. +1 −6 addons/base_address_extended/models/base_address_extended.py
  38. +6 −1 addons/base_geolocalize/models/base_geocoder.py
  39. +2 −2 addons/board/static/src/scss/dashboard.scss
  40. +47 −0 addons/board/static/tests/dashboard_tests.js
  41. +1 −1 addons/calendar/models/res_partner.py
  42. +4 −1 addons/delivery/models/product_template.py
  43. +1 −1 addons/digest/models/digest.py
  44. +2 −0 addons/hr_expense/wizard/hr_expense_sheet_register_payment.py
  45. +2 −1 addons/hr_expense/wizard/hr_expense_sheet_register_payment.xml
  46. +1 −1 addons/hr_holidays/models/hr_leave.py
  47. +4 −1 addons/hr_timesheet/models/hr_timesheet.py
  48. +5 −1 addons/http_routing/models/ir_http.py
  49. +1 −2 addons/hw_drivers/controllers/__init__.py
  50. +345 −376 addons/hw_drivers/controllers/driver.py
  51. +0 −34 addons/hw_drivers/controllers/loading.py
  52. BIN addons/hw_drivers/static/img/False.jpg
  53. BIN addons/hw_drivers/static/img/True.jpg
  54. +60 −98 addons/hw_posbox_homepage/controllers/main.py
  55. +2 −1 addons/hw_posbox_homepage/views/homepage.html
  56. +1 −1 addons/hw_posbox_homepage/views/remote_connect.html
  57. +3 −3 addons/l10n_be/__manifest__.py
  58. +4 −0 addons/l10n_be_edi/__init__.py
  59. +19 −0 addons/l10n_be_edi/__manifest__.py
  60. +3 −0 addons/l10n_be_edi/models/__init__.py
  61. +178 −0 addons/l10n_be_edi/models/account_invoice.py
  62. +118 −0 addons/l10n_be_edi/test_xml_file/efff_test.xml
  63. +3 −0 addons/l10n_be_edi/tests/__init__.py
  64. +33 −0 addons/l10n_be_edi/tests/test_ubl.py
  65. +2 −2 addons/l10n_generic_coa/data/account_invoice_demo.xml
  66. +4 −4 addons/l10n_in/views/report_invoice.xml
  67. +2 −2 addons/l10n_jp/data/account.tax.template.csv
  68. +28 −14 addons/l10n_multilang/models/l10n_multilang.py
  69. +4 −0 addons/l10n_mx/data/account_tax_data.xml
  70. +1 −1 addons/l10n_pl/data/account_tax_data.xml
  71. +4 −3 addons/mail/models/ir_attachment.py
  72. +10 −8 addons/mail/models/mail_mail.py
  73. +2 −2 addons/mail/models/mail_message.py
  74. +1 −1 addons/mail/models/mail_thread.py
  75. +4 −0 addons/mail/static/src/js/chatter.js
  76. +2 −3 addons/mail/static/src/js/document_viewer.js
  77. +17 −4 addons/mail/static/src/scss/chatter.scss
  78. +3 −0 addons/mail/static/src/scss/composer.scss
  79. +10 −10 addons/mail/static/src/xml/thread.xml
  80. +19 −0 addons/mail/static/tests/document_viewer_tests.js
  81. +2 −2 addons/mass_mailing/models/mass_mailing_stats.py
  82. +2 −1 addons/mass_mailing/wizard/mail_compose_message.py
  83. +39 −7 addons/mrp/models/mrp_abstract_workorder.py
  84. +10 −3 addons/mrp/models/mrp_bom.py
  85. +5 −13 addons/mrp/models/mrp_production.py
  86. +0 −5 addons/mrp/models/mrp_routing.py
  87. +200 −41 addons/mrp/models/mrp_workorder.py
  88. +1 −0 addons/mrp/models/res_config_settings.py
  89. +5 −0 addons/mrp/models/stock_picking.py
  90. +9 −4 addons/mrp/models/stock_production_lot.py
  91. +7 −10 addons/mrp/tests/test_order.py
  92. +6 −6 addons/mrp/views/mrp_bom_views.xml
  93. +1 −0 addons/mrp/views/mrp_production_views.xml
  94. +0 −6 addons/mrp/views/mrp_routing_views.xml
  95. +12 −5 addons/mrp/views/mrp_workorder_views.xml
  96. +11 −0 addons/mrp/views/res_config_settings_views.xml
  97. +5 −0 addons/mrp/views/stock_picking_views.xml
  98. +1 −1 addons/mrp/wizard/mrp_product_produce_views.xml
  99. +3 −0 addons/mrp_account/__init__.py
  100. +19 −0 addons/mrp_account/__manifest__.py
  101. +4 −0 addons/mrp_account/models/__init__.py
  102. +71 −0 addons/mrp_account/models/mrp_production.py
  103. +11 −0 addons/mrp_account/models/mrp_workcenter.py
  104. +3 −0 addons/mrp_account/tests/__init__.py
  105. +102 −0 addons/mrp_account/tests/test_mrp_account.py
  106. +1 −1 addons/mrp_byproduct/views/mrp_bom_views.xml
  107. +25 −0 addons/mrp_subcontracting/__init__.py
  108. +19 −0 addons/mrp_subcontracting/__manifest__.py
  109. +12 −0 addons/mrp_subcontracting/data/mrp_subcontracting_data.xml
  110. +9 −0 addons/mrp_subcontracting/models/__init__.py
  111. +20 −0 addons/mrp_subcontracting/models/mrp_bom.py
  112. +47 −0 addons/mrp_subcontracting/models/res_company.py
  113. +56 −0 addons/mrp_subcontracting/models/res_partner.py
  114. +41 −0 addons/mrp_subcontracting/models/stock_move.py
  115. +133 −0 addons/mrp_subcontracting/models/stock_picking.py
  116. +141 −0 addons/mrp_subcontracting/models/stock_warehouse.py
  117. +4 −0 addons/mrp_subcontracting/tests/__init__.py
  118. +525 −0 addons/mrp_subcontracting/tests/test_subcontracting.py
  119. +14 −0 addons/mrp_subcontracting/views/mrp_bom_views.xml
  120. +23 −0 addons/mrp_subcontracting/views/stock_picking_views.xml
  121. +13 −0 addons/mrp_subcontracting/views/stock_warehouse_views.xml
  122. +4 −4 addons/note/data/note_data.xml
  123. +1 −10 addons/payment/views/account_payment_views.xml
  124. +4 −2 addons/payment_authorize/models/authorize_request.py
  125. +2 −1 addons/point_of_sale/models/pos_session.py
  126. +0 −3 addons/point_of_sale/static/src/js/chrome.js
  127. +10 −5 addons/point_of_sale/static/src/js/models.js
  128. +3 −0 addons/point_of_sale/tools/posbox/overwrite_after_init/etc/cups/cupsd.conf
  129. +3 −3 addons/point_of_sale/tools/posbox/overwrite_after_init/etc/nginx/sites-enabled/default
  130. +1 −0 addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart
  131. +2 −0 ...point_of_sale/tools/posbox/overwrite_after_init/home/pi/odoo/addons/point_of_sale/__manifest__.py
  132. +20 −0 ..._of_sale/tools/posbox/overwrite_after_init/usr/local/lib/python3.5/dist-packages/v4l2.py.iotpatch
  133. +14 −3 addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
  134. +8 −0 addons/point_of_sale/tools/posbox/posbox_create_image.sh
  135. +2 −3 addons/point_of_sale/tools/posbox/posbox_download_images.sh
  136. +1 −1 addons/pos_hr/__manifest__.py
  137. +5 −1 addons/product/models/product.py
  138. +7 −4 addons/product/models/product_template.py
  139. +43 −0 addons/product/tests/test_product_attribute_value_config.py
  140. +3 −2 addons/product/views/product_views.xml
  141. +4 −0 addons/purchase/models/account_invoice.py
  142. +1 −1 addons/purchase/models/purchase.py
  143. +2 −2 addons/purchase/views/purchase_views.xml
  144. +4 −0 addons/purchase_mrp_subcontracting/__init__.py
  145. +18 −0 addons/purchase_mrp_subcontracting/__manifest__.py
  146. +5 −0 addons/purchase_mrp_subcontracting/models/__init__.py
  147. +16 −0 addons/purchase_mrp_subcontracting/models/product.py
  148. +16 −0 addons/purchase_mrp_subcontracting/models/stock_picking.py
  149. +7 −0 addons/purchase_mrp_subcontracting/tests/__init__.py
  150. +113 −0 addons/purchase_mrp_subcontracting/tests/test_purchase_subcontracting.py
  151. +25 −0 addons/purchase_mrp_subcontracting/views/supplier_info_views.xml
  152. +3 −2 addons/purchase_requisition/models/product.py
  153. +3 −2 addons/purchase_stock/models/account_invoice.py
  154. +6 −0 addons/purchase_stock/models/purchase.py
  155. +2 −2 addons/purchase_stock/models/stock_rule.py
  156. +1 −0 addons/sale/models/res_company.py
  157. +17 −14 addons/sale/models/sale.py
  158. +17 −20 addons/sale/report/sale_report_templates.xml
  159. +2 −1 addons/sale/static/src/js/tour.js
  160. +17 −20 addons/sale/views/sale_portal_templates.xml
  161. +1 −1 addons/sale_coupon/models/sale_coupon_program.py
  162. +2 −1 addons/sale_management/models/sale_order.py
  163. +1 −1 addons/sale_management/models/sale_order_template.py
  164. +1 −0 addons/sale_management/views/sale_portal_templates.xml
  165. +1 −1 addons/sale_product_configurator/static/src/js/product_configurator_controller.js
  166. +3 −1 addons/sale_timesheet/models/project_overview.py
  167. +4 −0 addons/snailmail/static/tests/chatter_snailmail_tests.js
  168. +8 −5 addons/stock/models/res_company.py
  169. +6 −6 addons/stock/models/stock_inventory.py
  170. +3 −2 addons/stock/models/stock_picking.py
  171. +5 −2 addons/stock/models/stock_production_lot.py
  172. +1 −1 addons/stock/models/stock_quant.py
  173. +7 −5 addons/stock/models/stock_warehouse.py
  174. +1 −0 addons/stock/report/report_stockinventory.xml
  175. +2 −2 addons/stock/views/res_partner_views.xml
  176. +1 −1 addons/stock/views/stock_picking_views.xml
  177. +1 −1 addons/stock/wizard/stock_immediate_transfer.py
  178. +32 −6 addons/stock_account/models/stock.py
  179. +45 −0 addons/stock_account/tests/test_stockvaluation.py
  180. +1 −1 addons/stock_account/views/product_views.xml
  181. +1 −1 addons/survey/controllers/main.py
  182. +1 −1 addons/survey/data/survey_demo_certification.xml
  183. +4 −2 addons/survey/models/survey_survey.py
  184. +4 −1 addons/survey/static/src/js/survey.js
  185. +21 −20 addons/web/static/src/js/chrome/systray_menu.js
  186. +2 −2 addons/web/static/src/js/core/domain.js
  187. +6 −2 addons/web/static/src/js/views/basic/basic_renderer.js
  188. +1 −0 addons/web/static/src/js/views/calendar/calendar_controller.js
  189. +17 −3 addons/web/static/src/js/views/list/list_editable_renderer.js
  190. +7 −0 addons/web/static/src/scss/layout_background.scss
  191. +1 −1 addons/web/static/src/scss/list_view.scss
  192. +43 −0 addons/web/static/tests/chrome/systray_tests.js
  193. +0 −1 addons/web/static/tests/helpers/test_utils_create.js
  194. +36 −0 addons/web/static/tests/views/calendar_tests.js
  195. +156 −0 addons/web/static/tests/views/list_tests.js
  196. +1 −0 addons/web/views/webclient_templates.xml
  197. +2 −2 addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js
  198. +3 −3 addons/web_editor/static/src/js/wysiwyg/widgets/media.js
  199. +110 −0 addons/web_editor/static/src/scss/web_editor.common.scss
  200. +8 −1 addons/website/models/ir_qweb.py
  201. +2 −1 addons/website/static/src/js/backend/dashboard.js
  202. +0 −110 addons/website/static/src/scss/website.editor.ui.scss
  203. +122 −0 addons/website/tests/test_qweb.py
  204. +33 −1 addons/website_crm_partner_assign/models/crm_lead.py
  205. +5 −0 addons/website_crm_partner_assign/tests/test_partner_assign.py
  206. +22 −5 addons/website_sale/models/sale_order.py
  207. +1 −4 addons/website_sale/static/src/js/website_sale_tour_buy.js
  208. +1 −54 addons/website_sale/static/src/js/website_sale_tour_shop_custom_attribute_value.js
  209. +3 −0 addons/website_sale_coupon/views/website_sale_templates.xml
  210. +19 −0 addons/website_sale_product_configurator/static/src/js/website_sale_tour_buy.js
  211. +69 −0 ...website_sale_product_configurator/static/src/js/website_sale_tour_shop_custom_attributes_value.js
  212. +2 −0 addons/website_sale_product_configurator/views/assets.xml
  213. +15 −0 doc/cla/corporate/business-solutions-for-africa.md
  214. +1 −0 doc/cla/corporate/xoe-corp.md
  215. +9 −0 doc/cla/individual/andriisem.md
  216. +11 −0 doc/cla/individual/bletourmy.md
  217. +11 −0 doc/cla/individual/hviniciusg.md
  218. +11 −0 doc/cla/individual/matthewdwatkins.md
  219. +11 −0 doc/cla/individual/mmahgoub.md
  220. +5 −1 doc/howtos/themes.rst
  221. +1 −1 odoo/addons/base/data/res.lang.csv
  222. +2 −0 odoo/addons/base/models/ir_mail_server.py
  223. +11 −0 odoo/addons/base/models/ir_model.py
  224. +9 −0 odoo/addons/base/models/ir_module.py
  225. +41 −0 odoo/addons/base/models/ir_translation.py
  226. +2 −2 odoo/addons/base/models/res_bank.py
  227. +1 −1 odoo/addons/base/models/res_currency.py
  228. +87 −16 odoo/addons/base/models/res_partner.py
  229. +35 −0 odoo/addons/base/tests/test_base.py
  230. +2 −1 odoo/addons/base/views/res_bank_views.xml
  231. +1 −1 odoo/addons/test_main_flows/static/src/js/tour.js
  232. +3 −0 odoo/addons/test_testing_utilities/ir.model.access.csv
  233. +13 −0 odoo/addons/test_testing_utilities/menu.xml
  234. +28 −0 odoo/addons/test_testing_utilities/models.py
  235. +22 −2 odoo/addons/test_testing_utilities/tests/test_form_impl.py
  236. +5 −1 odoo/fields.py
  237. +3 −2 odoo/models.py
  238. +94 −42 odoo/tests/common.py
  239. +4 −0 odoo/tools/date_utils.py
@@ -24,6 +24,7 @@
'data/digest_data.xml',
'views/account_menuitem.xml',
'views/account_payment_view.xml',
'wizard/account_invoice_import_view.xml',
'wizard/account_unreconcile_view.xml',
'wizard/account_move_reversal_view.xml',
'views/account_move_views.xml',
@@ -49,7 +50,6 @@
'views/tax_adjustments.xml',
'wizard/wizard_tax_adjustments_view.xml',
'views/res_config_settings_views.xml',
'views/account_invoice_import_wizard_view.xml',
'views/account_journal_dashboard_view.xml',
'views/account_portal_templates.xml',
'views/report_payment_receipt_templates.xml',
@@ -670,6 +670,16 @@ msgstr ""
msgid "A tax fiscal position could be defined only one time on same taxes."
msgstr ""

#. module: account
#: code:addons/account/models/res_users.py:17
#, python-format
msgid "A user cannot have both Tax B2B and Tax B2C.\n"
"Problematic user(s): %s\n"
"You should go in General Settings, and choose to display Product Prices\n"
"either in 'Tax-Included' or in 'Tax-Excluded' mode\n"
"(or switch twice the mode if you are already in the desired one)."
msgstr ""

#. module: account
#: model:res.groups,name:account.group_warning_account
msgid "A warning can be set on a partner (Account)"
@@ -19,4 +19,4 @@
from . import reconciliation_widget
from . import account_incoterms
from . import digest
from . import account_invoice_import_wizard
from . import res_users
@@ -487,10 +487,10 @@ def _get_bank_statements_available_sources(self):
bank_id = fields.Many2one('res.bank', related='bank_account_id.bank_id', readonly=False)
post_at_bank_rec = fields.Boolean(string="Post At Bank Reconciliation", help="Whether or not the payments made in this journal should be generated in draft state, so that the related journal entries are only posted when performing bank reconciliation.")

# alias configuration for 'purchase' type journals
# alias configuration for journals
alias_id = fields.Many2one('mail.alias', string='Alias', copy=False)
alias_domain = fields.Char('Alias domain', compute='_compute_alias_domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
alias_name = fields.Char('Alias Name for Vendor Bills', related='alias_id.alias_name', help="It creates draft vendor bill by sending an email.", readonly=False)
alias_name = fields.Char('Alias Name', related='alias_id.alias_name', help="It creates draft invoices and bills by sending an email.", readonly=False)

journal_group_ids = fields.Many2many('account.journal.group', string="Journal Groups")

@@ -583,13 +583,13 @@ def onchange_credit_account_id(self):
self.default_debit_account_id = self.default_credit_account_id

@api.multi
def _get_alias_values(self, alias_name=None):
def _get_alias_values(self, type, alias_name=None):
if not alias_name:
alias_name = self.name
if self.company_id != self.env.ref('base.main_company'):
alias_name += '-' + str(self.company_id.name)
return {
'alias_defaults': {'type': 'in_invoice', 'company_id': self.company_id.id},
'alias_defaults': {'type': type == 'purchase' and 'in_invoice' or 'out_invoice', 'company_id': self.company_id.id},
'alias_parent_thread_id': self.id,
'alias_name': re.sub(r'[^\w]+', '-', alias_name)
}
@@ -617,7 +617,7 @@ def copy(self, default=None):

def _update_mail_alias(self, vals):
self.ensure_one()
alias_values = self._get_alias_values(alias_name=vals.get('alias_name'))
alias_values = self._get_alias_values(type=vals.get('type') or self.type, alias_name=vals.get('alias_name'))
if self.alias_id:
self.alias_id.write(alias_values)
else:
@@ -663,7 +663,7 @@ def write(self, vals):
bank_account = self.env['res.partner.bank'].browse(vals['bank_account_id'])
if bank_account.partner_id != company.partner_id:
raise UserError(_("The partners of the journal's company and the related bank account mismatch."))
if vals.get('type') == 'purchase':
if 'alias_name' in vals:
journal._update_mail_alias(vals)
result = super(AccountJournal, self).write(vals)

@@ -787,8 +787,7 @@ def create(self, vals):
if vals.get('type') in ('sale', 'purchase') and vals.get('refund_sequence') and not vals.get('refund_sequence_id'):
vals.update({'refund_sequence_id': self.sudo()._create_sequence(vals, refund=True).id})
journal = super(AccountJournal, self.with_context(mail_create_nolog=True)).create(vals)
if journal.type == 'purchase':
# create a mail alias for purchase journals (always, deactivated if alias_name isn't set)
if 'alias_name' in vals:
journal._update_mail_alias(vals)

# Create the bank_account_id if necessary
@@ -235,14 +235,18 @@ def button_confirm_bank(self):
statements = self.filtered(lambda r: r.state == 'open')
for statement in statements:
moves = self.env['account.move']
# `line.journal_entry_ids` gets invalidated from the cache during the loop
# because new move lines are being created at each iteration.
# The below dict is to prevent the ORM to permanently refetch `line.journal_entry_ids`
line_journal_entries = {line: line.journal_entry_ids for line in statement.line_ids}
for st_line in statement.line_ids:
#upon bank statement confirmation, look if some lines have the account_id set. It would trigger a journal entry
#creation towards that account, with the wanted side-effect to skip that line in the bank reconciliation widget.
journal_entries = line_journal_entries[st_line]
st_line.fast_counterpart_creation()
if not st_line.account_id and not st_line.journal_entry_ids.ids and not st_line.statement_id.currency_id.is_zero(st_line.amount):
if not st_line.account_id and not journal_entries.ids and not st_line.statement_id.currency_id.is_zero(st_line.amount):
raise UserError(_('All the account entries lines must be processed in order to close the statement.'))
for aml in st_line.journal_entry_ids:
moves |= aml.move_id
moves = statement.mapped('line_ids.journal_entry_ids.move_id')
if moves:
moves.filtered(lambda m: m.state != 'posted').post()
statement.message_post(body=_('Statement %s confirmed, journal items were created.') % (statement.name,))
@@ -103,6 +103,11 @@ def _default_comment(self):
if invoice_type == 'out_invoice' and self.env['ir.config_parameter'].sudo().get_param('account.use_invoice_terms'):
return self.env.user.company_id.invoice_terms

def _get_aml_for_amount_residual(self):
""" Get the aml to consider to compute the amount residual of invoices """
self.ensure_one()
return self.sudo().move_id.line_ids.filtered(lambda l: l.account_id == self.account_id)

@api.one
@api.depends(
'state', 'currency_id', 'invoice_line_ids.price_subtotal',
@@ -112,14 +117,13 @@ def _compute_residual(self):
residual = 0.0
residual_company_signed = 0.0
sign = self.type in ['in_refund', 'out_refund'] and -1 or 1
for line in self.sudo().move_id.line_ids:
if line.account_id == self.account_id:
residual_company_signed += line.amount_residual
if line.currency_id == self.currency_id:
residual += line.amount_residual_currency if line.currency_id else line.amount_residual
else:
from_currency = line.currency_id or line.company_id.currency_id
residual += from_currency._convert(line.amount_residual, self.currency_id, line.company_id, line.date or fields.Date.today())
for line in self._get_aml_for_amount_residual():
residual_company_signed += line.amount_residual
if line.currency_id == self.currency_id:
residual += line.amount_residual_currency if line.currency_id else line.amount_residual
else:
from_currency = line.currency_id or line.company_id.currency_id
residual += from_currency._convert(line.amount_residual, self.currency_id, line.company_id, line.date or fields.Date.today())
self.residual_company_signed = abs(residual_company_signed) * sign
self.residual_signed = abs(residual) * sign
self.residual = abs(residual)
@@ -1000,7 +1004,7 @@ def action_invoice_open(self):
# lots of duplicate calls to action_invoice_open, so we remove those already open
to_open_invoices = self.filtered(lambda inv: inv.state != 'open')
if to_open_invoices.filtered(lambda inv: not inv.partner_id):
raise UserError(_("The field Vendor is required, please complete it to validate the Vendor Bill."))
raise UserError(_("The field Vendor/Customer is required, please complete it to validate the Vendor Bill/Customer Invoice."))
if to_open_invoices.filtered(lambda inv: inv.state != 'draft'):
raise UserError(_("Invoice must be in draft state in order to validate it."))
if to_open_invoices.filtered(lambda inv: float_compare(inv.amount_total, 0.0, precision_rounding=inv.currency_id.rounding) == -1):
@@ -1032,6 +1036,10 @@ def action_invoice_re_open(self):
raise UserError(_('Invoice must be paid in order to set it to register payment.'))
return self.write({'state': 'open'})

@api.multi
def action_register_payment(self):
return self.env['account.payment'].with_context(active_ids=self.ids, active_model='account.invoice', active_id=self.id).action_register_payment()

@api.multi
def action_invoice_cancel(self):
return self.filtered(lambda inv: inv.state != 'cancel').action_cancel()
@@ -1110,12 +1118,18 @@ def get_taxes_values(self, tax_group_fields=False):
tax_grouped[key][field] += round_curr(val.get(field) or 0)
return tax_grouped

@api.multi
def _get_aml_for_register_payment(self):
""" Get the aml to consider to reconcile in register payment """
self.ensure_one()
return self.move_id.line_ids.filtered(lambda r: not r.reconciled and r.account_id.internal_type in ('payable', 'receivable'))

@api.multi
def register_payment(self, payment_line, writeoff_acc_id=False, writeoff_journal_id=False):
""" Reconcile payable/receivable lines from the invoice with payment_line """
line_to_reconcile = self.env['account.move.line']
for inv in self:
line_to_reconcile += inv.move_id.line_ids.filtered(lambda r: not r.reconciled and r.account_id.internal_type in ('payable', 'receivable'))
line_to_reconcile += inv._get_aml_for_register_payment()
return (line_to_reconcile + payment_line).reconcile(writeoff_acc_id, writeoff_journal_id)

@api.multi
@@ -816,7 +816,9 @@ def check_full_reconcile(self):
total_amount_currency = 0
maxdate = date.min
to_balance = {}
cash_basis_partial = self.env['account.partial.reconcile']
for aml in amls:
cash_basis_partial |= aml.move_id.tax_cash_basis_rec_id
total_debit += aml.debit
total_credit += aml.credit
maxdate = max(aml.date, maxdate)
@@ -831,15 +833,28 @@ def check_full_reconcile(self):
to_balance[aml.currency_id] = [self.env['account.move.line'], 0]
to_balance[aml.currency_id][0] += aml
to_balance[aml.currency_id][1] += aml.amount_residual != 0 and aml.amount_residual or aml.amount_residual_currency

# Check if reconciliation is total
# To check if reconciliation is total we have 3 differents use case:
# 1) There are multiple currency different than company currency, in that case we check using debit-credit
# 2) We only have one currency which is different than company currency, in that case we check using amount_currency
# 3) We have only one currency and some entries that don't have a secundary currency, in that case we check debit-credit
# or amount_currency.
# 4) Cash basis full reconciliation
# - either none of the moves are cash basis reconciled, and we proceed
# - or some moves are cash basis reconciled and we make sure they are all fully reconciled

digits_rounding_precision = amls[0].company_id.currency_id.rounding
if (currency and float_is_zero(total_amount_currency, precision_rounding=currency.rounding)) or \
(multiple_currency and float_compare(total_debit, total_credit, precision_rounding=digits_rounding_precision) == 0):
if (
(
not cash_basis_partial or (cash_basis_partial and all([p >= 1.0 for p in amls._get_matched_percentage().values()]))
) and
(
currency and float_is_zero(total_amount_currency, precision_rounding=currency.rounding) or
multiple_currency and float_compare(total_debit, total_credit, precision_rounding=digits_rounding_precision) == 0
)
):

exchange_move_id = False
# Eventually create a journal entry to book the difference due to foreign currency's exchange rate that fluctuates
if to_balance and any([not float_is_zero(residual, precision_rounding=digits_rounding_precision) for aml, residual in to_balance.values()]):
@@ -933,7 +948,8 @@ def _reconcile_lines(self, debit_moves, credit_moves, field):

for after_rec_dict in cash_basis_subjected:
new_rec = part_rec.create(after_rec_dict)
if cash_basis:
# if the pair belongs to move being reverted, do not create CABA entry
if cash_basis and not (new_rec.debit_move_id + new_rec.credit_move_id).mapped('move_id').mapped('reverse_entry_id'):
new_rec.create_tax_cash_basis_entry(cash_basis_percentage_before_rec)
self.recompute()

Oops, something went wrong.

0 comments on commit 0a09a4d

Please sign in to comment.
You can’t perform that action at this time.