# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
#
##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, withAbort, simulate

from zExceptions import Unauthorized
from DateTime import DateTime
import time

class TestSlapOSAccounting(SlapOSTestCaseMixin):

  def createHostingSubscription(self):
    new_id = self.generateNewId()
    return self.portal.hosting_subscription_module.newContent(
      portal_type='Hosting Subscription',
      title="Subscription %s" % new_id,
      reference="TESTHS-%s" % new_id,
      )

  def createInstanceTree(self):
    new_id = self.generateNewId()
    return self.portal.instance_tree_module.newContent(
      portal_type='Instance Tree',
      title="Subscription %s" % new_id,
      reference="TESTIT-%s" % new_id,
      )

  def createOpenSaleOrder(self):
    new_id = self.generateNewId()
    return self.portal.open_sale_order_module.newContent(
      portal_type='Open Sale Order',
      title="OpenSaleOrder %s" % new_id,
      reference="TESTOSO-%s" % new_id,
      )

  @withAbort
  def test_HS_calculateSubscriptionStartDate_REQUEST_disallowed(self):
    item = self.createHostingSubscription()
    self.assertRaises(
      Unauthorized,
      item.HostingSubscription_calculateSubscriptionStartDate,
      REQUEST={})

  @withAbort
  def test_HS_calculateSubscriptionStartDate_noWorkflow(self):
    item = self.createHostingSubscription()
    item.workflow_history['instance_slap_interface_workflow'] = []
    date = item.HostingSubscription_calculateSubscriptionStartDate()
    self.assertEqual(date, item.getCreationDate().earliestTime())

  @withAbort
  def test_HS_calculateSubscriptionStartDate_withRequest(self):
    item = self.createHostingSubscription()
    item.workflow_history['edit_workflow'] = [{
        'comment':'Directly request the instance',
        'error_message': '',
        'actor': 'ERP5TypeTestCase',
        'time': DateTime('2012/11/15 11:11'),
        'action': 'edit'
        }]
    date = item.HostingSubscription_calculateSubscriptionStartDate()
    self.assertEqual(date, DateTime('2012/11/15'))

  @withAbort
  def test_HS_calculateSubscriptionStartDate_withRequestEndOfMonth(self):
    item = self.createHostingSubscription()
    item.workflow_history['edit_workflow'] = [{
        'comment':'Directly request the instance',
        'error_message': '',
        'actor': 'ERP5TypeTestCase',
        'time': DateTime('2012/11/30 11:11'),
        'action': 'edit'
    }]
    date = item.HostingSubscription_calculateSubscriptionStartDate()
    self.assertEqual(date, DateTime('2012/11/30'))

  @withAbort
  def test_HS_calculateSubscriptionStopDate_REQUEST_disallowed(self):
    item = self.createInstanceTree()
    self.assertRaises(
      Unauthorized,
      item.InstanceTree_calculateSubscriptionStopDate,
      REQUEST={})

  @withAbort
  def test_HS_calculateSubscriptionStopDate_withDestroy(self):
    item = self.createInstanceTree()
    destroy_date = DateTime('2012/10/30')
    item.workflow_history['instance_slap_interface_workflow'].append({
        'comment':'Directly destroy',
        'error_message': '',
        'actor': 'ERP5TypeTestCase',
        'slap_state': 'destroy_requested',
        'time': destroy_date,
        'action': 'request_destroy'
    })
    date = item.InstanceTree_calculateSubscriptionStopDate()
    self.assertEqual(date, DateTime('2012/10/31'))

  @withAbort
  def test_HS_calculateSubscriptionStopDate_noDestroy(self):
    item = self.createInstanceTree()
    item.workflow_history['instance_slap_interface_workflow'] = []
    date = item.InstanceTree_calculateSubscriptionStopDate()
    self.assertEqual(date, None)

  def test_OpenSaleOrder_reindexIfIndexedBeforeLine_no_line(self):
    portal = self.portal
    order = self.createOpenSaleOrder()
    self.tic()
    indexation_timestamp = portal.portal_catalog(
      uid=order.getUid(),
      select_dict={'indexation_timestamp': None})[0].indexation_timestamp
    order.OpenSaleOrder_reindexIfIndexedBeforeLine()
    self.tic()
    new_indexation_timestamp = portal.portal_catalog(
      uid=order.getUid(),
      select_dict={'indexation_timestamp': None})[0].indexation_timestamp
    self.assertEqual(new_indexation_timestamp,
                      indexation_timestamp)

  def test_OpenSaleOrder_reindexIfIndexedBeforeLine_line_indexed_after(self):
    portal = self.portal
    order = self.createOpenSaleOrder()
    line = order.newContent(portal_type="Open Sale Order Line")
    self.tic()
    line.activate().immediateReindexObject()
    # XXX One more kitten killed
    time.sleep(1)
    self.tic()
    indexation_timestamp = portal.portal_catalog(
      uid=order.getUid(),
      select_dict={'indexation_timestamp': None})[0].indexation_timestamp
    order.OpenSaleOrder_reindexIfIndexedBeforeLine()
    self.tic()
    new_indexation_timestamp = portal.portal_catalog(
      uid=order.getUid(),
      select_dict={'indexation_timestamp': None})[0].indexation_timestamp
    self.assertNotEqual(new_indexation_timestamp,
                         indexation_timestamp)

  def test_OpenSaleOrder_reindexIfIndexedBeforeLine_line_indexed_before(self):
    portal = self.portal
    order = self.createOpenSaleOrder()
    order.newContent(portal_type="Open Sale Order Line")
    self.tic()
    order.activate().immediateReindexObject()
    # XXX One more kitten killed
    time.sleep(1)
    self.tic()
    indexation_timestamp = portal.portal_catalog(
      uid=order.getUid(),
      select_dict={'indexation_timestamp': None})[0].indexation_timestamp
    order.OpenSaleOrder_reindexIfIndexedBeforeLine()
    self.tic()
    new_indexation_timestamp = portal.portal_catalog(
      uid=order.getUid(),
      select_dict={'indexation_timestamp': None})[0].indexation_timestamp
    self.assertEqual(new_indexation_timestamp,
                      indexation_timestamp)

  def test_OpenSaleOrder_reindexIfIndexedBeforeLine_REQUEST_disallowed(self):
    self.assertRaises(
      Unauthorized,
      self.portal.OpenSaleOrder_reindexIfIndexedBeforeLine,
      REQUEST={})


  @simulate("SaleInvoiceTransaction_createReversalPayzenTransaction", 
            "*args, **kwargs",  """context.portal_workflow.doActionFor(context, action='edit_action', comment='Visited by SaleInvoiceTransaction_createReversalPayzenTransaction')
return context.getParentValue()""")
  def test_SaleInvoiceTransaction_createSlapOSReversalTransaction_payzen(self):
    sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction")
    sale_invoice_transaction.edit(payment_mode="payzen")

    redirect = sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()
    self.assertTrue(redirect.endswith('accounting_module?portal_status_message=Reversal%20Transaction%20created.'), 
      "%s doesn't end with sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()" % redirect)
    self.assertEqual(
        'Visited by SaleInvoiceTransaction_createReversalPayzenTransaction',
        sale_invoice_transaction.workflow_history['edit_workflow'][-1]['comment'])

  @simulate("SaleInvoiceTransaction_createReversalWechatTransaction", 
            "*args, **kwargs",  """context.portal_workflow.doActionFor(context, action='edit_action', comment='Visited by SaleInvoiceTransaction_createReversalWechatTransaction')
return context.getParentValue()""")
  def test_SaleInvoiceTransaction_createSlapOSReversalTransaction_wechat(self):
    sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction")
    sale_invoice_transaction.edit(payment_mode="wechat")

    redirect = sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()
    self.assertTrue(redirect.endswith('accounting_module?portal_status_message=Reversal%20Transaction%20created.'), 
      "%s doesn't end with sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()" % redirect)
    self.assertEqual(
        'Visited by SaleInvoiceTransaction_createReversalWechatTransaction',
        sale_invoice_transaction.workflow_history['edit_workflow'][-1]['comment'])

  def test_SaleInvoiceTransaction_createSlapOSReversalTransaction_unknown(self):
    sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction")
    sale_invoice_transaction.edit(payment_mode="unknown")

    redirect = sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()

    self.assertTrue(redirect.endswith('%s?portal_status_message=The%%20payment%%20mode%%20is%%20unsupported.' % sale_invoice_transaction.getRelativeUrl()), 
      "%s doesn't end with %s?portal_status_message=The%%20payment%%20mode%%20is%%20unsupported." % (redirect, sale_invoice_transaction.getRelativeUrl()))

  def test_SaleInvoiceTransaction_resetPaymentMode(self):
    sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction")
    sale_invoice_transaction.edit(payment_mode="unknown",
      start_date=DateTime(),
      stop_date=DateTime())
    sale_invoice_transaction.confirm()
    sale_invoice_transaction.start( )
    sale_invoice_transaction.stop()

    sale_invoice_transaction.SaleInvoiceTransaction_resetPaymentMode()
    self.assertEqual(sale_invoice_transaction.getPaymentMode(), "unknown")
    sale_invoice_transaction.edit(payment_mode="payzen")

    sale_invoice_transaction.SaleInvoiceTransaction_resetPaymentMode()
    self.assertEqual(sale_invoice_transaction.getPaymentMode(), None)
    sale_invoice_transaction.edit(payment_mode="wechat")

    sale_invoice_transaction.SaleInvoiceTransaction_resetPaymentMode()
    self.assertEqual(sale_invoice_transaction.getPaymentMode(), None)

    self.assertRaises(
      Unauthorized,
      sale_invoice_transaction.SaleInvoiceTransaction_resetPaymentMode,
      REQUEST={})