================================ Sale Subscription Asset Scenario ================================ Imports:: >>> import datetime >>> from decimal import Decimal >>> from proteus import Model >>> from trytond.modules.account.tests.tools import create_chart, get_accounts >>> from trytond.modules.company.tests.tools import create_company >>> from trytond.tests.tools import activate_modules, assertEqual Activate modules:: >>> config = activate_modules( ... 'sale_subscription_asset', create_company, create_chart) Get accounts:: >>> accounts = get_accounts() >>> revenue = accounts['revenue'] Create party:: >>> Party = Model.get('party.party') >>> customer = Party(name='Customer') >>> customer.save() Create some assets:: >>> ProductTemplate = Model.get('product.template') >>> Uom = Model.get('product.uom') >>> unit, = Uom.find([('name', '=', 'Unit')]) >>> template = ProductTemplate() >>> template.name = 'Asset' >>> template.default_uom = unit >>> template.type = 'assets' >>> template.list_price = Decimal(1000) >>> template.save() >>> asset, = template.products And some lots linked to the asset:: >>> StockLot = Model.get('stock.lot') >>> lot1 = StockLot(number='001', product=asset) >>> lot1.save() >>> lot2 = StockLot(number='002', product=asset) >>> lot2.save() Create subscription recurrence rule sets:: >>> RecurrenceRuleSet = Model.get('sale.subscription.recurrence.rule.set') >>> monthly = RecurrenceRuleSet(name='Monthly') >>> rule, = monthly.rules >>> rule.freq = 'monthly' >>> rule.interval = 1 >>> monthly.save() Create subscription service:: >>> template = ProductTemplate() >>> template.name = 'Rental' >>> template.default_uom = unit >>> template.type = 'service' >>> template.list_price = Decimal('10') >>> template.save() >>> product, = template.products >>> Service = Model.get('sale.subscription.service') >>> service = Service() >>> service.product = product >>> service.asset_lots.extend([lot1, lot2]) >>> service.save() >>> sorted(l.number for l in service.asset_lots_available) ['001', '002'] Subscribe:: >>> Subscription = Model.get('sale.subscription') >>> subscription = Subscription() >>> subscription.party = customer >>> subscription.start_date = datetime.date(2016, 1, 1) >>> subscription.invoice_start_date = datetime.date(2016, 2, 1) >>> subscription.invoice_recurrence = monthly >>> line = subscription.lines.new() >>> line.service = service >>> line.quantity = 1 >>> subscription.click('quote') >>> subscription.click('run') Traceback (most recent call last): ... RequiredValidationError: ... >>> subscription.click('draft') >>> line, = subscription.lines >>> line.asset_lot = lot1 >>> subscription.click('quote') >>> subscription.click('run') >>> with config.set_context(date=datetime.date(2017, 1, 1)): ... lot1.reload() ... subscribed_line = lot1.subscribed ... service.reload() ... lots_available = sorted( ... l.number for l in service.asset_lots_available) >>> assertEqual(subscribed_line, line) >>> lots_available ['002'] Creating an overlapping line won't work:: >>> overlapping = Subscription() >>> overlapping.party = customer >>> overlapping.start_date = datetime.date(2017, 1, 1) >>> overlapping.invoice_start_date = datetime.date(2017, 2, 1) >>> overlapping.invoice_recurrence = monthly >>> line = overlapping.lines.new() >>> line.service = service >>> line.start_date = datetime.date(2017, 1, 1) >>> line.quantity = 1 >>> line.asset_lot = lot1 >>> overlapping.save() Traceback (most recent call last): ... SQLConstraintError: .... Cancelling the subscription will remove lot from the lines thus making it available again:: >>> another_subscription = Subscription() >>> another_subscription.party = customer >>> another_subscription.start_date = datetime.date(2018, 1, 1) >>> another_subscription.invoice_start_date = datetime.date(2018, 2, 1) >>> another_subscription.invoice_recurrence = monthly >>> line = another_subscription.lines.new() >>> line.service = service >>> line.asset_lot = lot2 >>> line.quantity = 1 >>> another_subscription.click('quote') >>> service.reload() >>> sorted(l.number for l in service.asset_lots_available) [] >>> another_subscription.click('cancel') >>> [l.asset_lot for l in another_subscription.lines] [None] >>> service.reload() >>> sorted(l.number for l in service.asset_lots_available) ['002']