Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contract/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"data/ir_ui_menu.xml",
"wizards/contract_line_wizard.xml",
"wizards/contract_manually_create_invoice.xml",
"wizards/contract_manually_single_invoice.xml",
"wizards/contract_contract_terminate.xml",
"views/contract_tag.xml",
"views/abstract_contract_line.xml",
Expand Down
20 changes: 15 additions & 5 deletions contract/models/abstract_contract_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,27 @@ def _inverse_price_unit(self):
for line in self.filtered(lambda x: not x.automatic_price):
line.specific_price = line.price_unit

def _get_discounted_price_subtotal(self):
"""Return the discounted price subtotal"""
subtotal = self._get_price_subtotal()
discount = self.discount / 100
subtotal *= 1 - discount
return subtotal

def _get_price_subtotal(self):
"""Return the subtotal price (without discount)"""
self.ensure_one()
return self.quantity * self.price_unit

@api.depends("quantity", "price_unit", "discount")
def _compute_price_subtotal(self):
for line in self:
subtotal = line.quantity * line.price_unit
discount = line.discount / 100
subtotal *= 1 - discount
subtotal_discounted = line._get_discounted_price_subtotal()
if line.contract_id.pricelist_id:
cur = line.contract_id.pricelist_id.currency_id
line.price_subtotal = cur.round(subtotal)
line.price_subtotal = cur.round(subtotal_discounted)
else:
line.price_subtotal = subtotal
line.price_subtotal = subtotal_discounted

@api.constrains("discount")
def _check_discount(self):
Expand Down
51 changes: 47 additions & 4 deletions contract/models/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,37 @@ def _compute_group_id(self):
if len(set(all_analytic_accounts)) == 1:
record.group_id = all_analytic_accounts[0]

def generate_invoices_manually(self, date=None):
if date is None:
date = fields.Date.today()
while (
self.recurring_next_date
and self.recurring_next_date <= date
and (not self.date_end or self.recurring_next_date <= self.date_end)
):
_logger.info(
f"next date {self.recurring_next_date} <= {date}, "
f"date end {self.date_end} "
)
# We create the invoices for the contract lines
result = self.with_company(self.company_id.id)._cron_recurring_create(
self.recurring_next_date,
create_type=self.generation_type,
domain=[("id", "=", self.id)],
)
for record_list in result:
for record in record_list:
self.message_post(
body=_(
"Contract manually generated: "
f'<a href="#" data-oe-model="{record._name}"'
f' data-oe-id="{record.id}">'
f"{record.display_name}"
"</a>"
)
)
return True

def get_formview_id(self, access_uid=None):
if self.contract_type == "sale":
return self.env.ref("contract.contract_contract_customer_form_view").id
Expand All @@ -193,6 +224,10 @@ def write(self, vals):
@api.model
def _set_start_contract_modification(self):
subtype_id = self.env.ref("contract.mail_message_subtype_contract_modification")
_logger.warning(
"recurring_create_invoice is deprecated in favor of "
"_recurring_create_invoice instead"
)
for record in self:
if record.contract_line_ids:
date_start = min(record.contract_line_ids.mapped("date_start"))
Expand Down Expand Up @@ -669,17 +704,24 @@ def _get_recurring_create_func(self, create_type="invoice"):
return self.__class__._recurring_create_invoice

@api.model
def _cron_recurring_create(self, date_ref=False, create_type="invoice"):
def _cron_recurring_create(
self, date_ref=False, create_type="invoice", domain=None
):
"""
The cron function in order to create recurrent documents
from contracts.
The domain is used to add an extra filter
"""
if domain is None:
domain = []
_recurring_create_func = self._get_recurring_create_func(
create_type=create_type
)
if not date_ref:
date_ref = fields.Date.context_today(self)
domain = self._get_contracts_to_invoice_domain(date_ref)
domain = expression.AND(
[domain, self._get_contracts_to_invoice_domain(date_ref)]
)
domain = expression.AND(
[
domain,
Expand All @@ -688,6 +730,7 @@ def _cron_recurring_create(self, date_ref=False, create_type="invoice"):
)
contracts = self.search(domain)
companies = set(contracts.mapped("company_id"))
result = []
# Invoice by companies, so assignation emails get correct context
for company in companies:
contracts_to_invoice = contracts.filtered(
Expand All @@ -697,8 +740,8 @@ def _cron_recurring_create(self, date_ref=False, create_type="invoice"):
or contract.recurring_next_date <= contract.date_end
)
).with_company(company)
_recurring_create_func(contracts_to_invoice, date_ref)
return True
result.append(_recurring_create_func(contracts_to_invoice, date_ref))
return result

@api.model
def cron_recurring_create_invoice(self, date_ref=None):
Expand Down
1 change: 1 addition & 0 deletions contract/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"contract_line_wizard","contract_line_wizard","model_contract_line_wizard","account.group_account_manager",1,1,1,1
"contract_manually_create_invoice_wizard","contract_manually_create_invoice_wizard","model_contract_manually_create_invoice","account.group_account_invoice",1,1,1,1
"contract_contract_terminate_wizard","contract_contract_terminate_wizard","model_contract_contract_terminate","contract.can_terminate_contract",1,1,1,1
"contract_manually_single_invoice_wizard","contract_manually_single_process_wizard","model_contract_manually_single_invoice","account.group_account_invoice",1,1,1,1
Loading
Loading