InventoryBrain.py 11.9 KB
Newer Older
Jean-Paul Smets's avatar
Jean-Paul Smets committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
##############################################################################
#
# Copyright (c) 2002 Nexedi SARL. All Rights Reserved.
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################

from Products.ZSQLCatalog.zsqlbrain import ZSQLBrain
from DateTime import DateTime
from ZTUtils import make_query

Sebastien Robin's avatar
Sebastien Robin committed
19
from Products.CMFCore.utils import getToolByName
Jean-Paul Smets's avatar
Jean-Paul Smets committed
20 21 22 23 24 25 26 27 28 29 30 31 32
from zLOG import LOG

class InventoryBrain(ZSQLBrain):
  """
    Global analysis (all variations and categories)
  """

  # Stock management
  def getInventory(self, at_date = None, ignore_variation=0, simulation_state=None, **kw):
    if type(simulation_state) is type('a'):
      simulation_state = [simulation_state]
    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
                                          to_date=at_date, omit_simulation = 0,
33
                                          section_category = self.getPortalDefaultSectionCategory(),
Jean-Paul Smets's avatar
Jean-Paul Smets committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47
                                          simulation_state=simulation_state)
    inventory = None
    if len(result) > 0:
      inventory = result[0].inventory
    if inventory is None:
      return 0.0
    else:
      return inventory

  #getCurrentInventory = 10.0
  def getCurrentInventory(self):
    """
      Returns current inventory
    """
48
    return self.getInventory(simulation_state=self.getPortalCurrentInventoryStateList(), ignore_variation=1)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
49 50 51 52 53 54
    #return self.getInventory(at_date=DateTime(), ignore_variation=1)

  def getFutureInventory(self):
    """
      Returns current inventory
    """
55 56 57 58
    return self.getInventory(ignore_variation=1,
                             simulation_state=list(self.getPortalFutureInventoryStateList())+ \
                                              list(self.getPortalReservedInventoryStateList())+ \
                                              list(self.getPortalCurrentInventoryStateList()))
Jean-Paul Smets's avatar
Jean-Paul Smets committed
59 60 61 62 63 64 65 66

  def getAvailableInventory(self):
    """
      Returns current inventory
    """
    at_date=DateTime()
    current = self.getCurrentInventory()
    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], ignore_variation=1,
67
                                          omit_simulation = 1, omit_input = 1,
68 69
                                          section_category = self.getPortalDefaultSectionCategory(),
                                          simulation_state = self.getPortalReservedInventoryStateList())
Jean-Paul Smets's avatar
Jean-Paul Smets committed
70 71 72 73 74
    reserved_inventory = None
    if len(result) > 0:
      reserved_inventory = result[0].inventory
    if reserved_inventory is None:
      reserved_inventory = 0.0
75 76
    return current + reserved_inventory

Jean-Paul Smets's avatar
Jean-Paul Smets committed
77 78 79 80
  def getQuantityUnit(self, **kw):
    try:
      resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
      return resource.getQuantityUnit()
Yoshinori Okuji's avatar
Yoshinori Okuji committed
81
    except AttributeError:
Jean-Paul Smets's avatar
Jean-Paul Smets committed
82 83 84 85 86 87 88 89 90
      return ''


class InventoryListBrain(ZSQLBrain):
  """
    Lists each variation
  """

  # Stock management
Sebastien Robin's avatar
Sebastien Robin committed
91 92 93 94 95 96 97
  def getInventory(self, **kw):
    """
    Returns the inventory
    """
    simulation_tool = getToolByName(self,'portal_simulation')
    return simulation_tool.getInventory(node=self.node_relative_url,variation_text=self.variation_text,
                                 resource=self.resource_relative_url,**kw)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
98 99

  #getCurrentInventory = 10.0
Sebastien Robin's avatar
Sebastien Robin committed
100
  def getCurrentInventory(self,**kw):
Jean-Paul Smets's avatar
Jean-Paul Smets committed
101 102 103
    """
      Returns current inventory
    """
Sebastien Robin's avatar
Sebastien Robin committed
104 105 106
    simulation_tool = getToolByName(self,'portal_simulation')
    return simulation_tool.getCurrentInventory(node=self.node_relative_url,variation_text=self.variation_text,
                                 resource=self.resource_relative_url,**kw)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
107

Sebastien Robin's avatar
Sebastien Robin committed
108
  def getFutureInventory(self,**kw):
Jean-Paul Smets's avatar
Jean-Paul Smets committed
109 110 111
    """
      Returns current inventory
    """
Sebastien Robin's avatar
Sebastien Robin committed
112 113 114
    simulation_tool = getToolByName(self,'portal_simulation')
    return simulation_tool.getFutureInventory(node=self.node_relative_url,variation_text=self.variation_text,
                                 resource=self.resource_relative_url,**kw)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
115

Sebastien Robin's avatar
Sebastien Robin committed
116
  def getAvailableInventory(self,**kw):
Jean-Paul Smets's avatar
Jean-Paul Smets committed
117 118 119
    """
      Returns current inventory
    """
Sebastien Robin's avatar
Sebastien Robin committed
120
    simulation_tool = getToolByName(self,'portal_simulation')
121 122 123 124
    return simulation_tool.getAvailableInventory(
                             node=self.node_relative_url,
                             variation_text=self.variation_text,
                             resource=self.resource_relative_url, **kw)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
125 126

  def getQuantity(self, **kw):
127 128 129 130 131 132 133 134 135 136 137
    """
    Return the quantity of the current delivery for a resource
    """
    total_kw = {
      'explanation_uid': self.getDeliveryUid(),
      'resource_uid': self.resource_uid,
      'variation_text': self.variation_text,
    }
    total_kw.update(self.portal_catalog.buildSQLQuery(query_table='movement',
                                                      **total_kw))
    result = self.Delivery_zGetTotal(**total_kw)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
138 139 140 141 142 143 144 145 146 147
    inventory = None
    if len(result) > 0:
      inventory = result[0].inventory
    if inventory is None:
      return 0.0
    else:
      return inventory

  def getQuantityUnit(self, **kw):
    try:
148 149
      resource = self.portal_categories.unrestrictedTraverse(
                                           self.resource_relative_url)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
150
      return resource.getQuantityUnit()
Yoshinori Okuji's avatar
Yoshinori Okuji committed
151
    except AttributeError:
Jean-Paul Smets's avatar
Jean-Paul Smets committed
152 153 154
      return ''

  def getListItemUrl(self, cname_id, selection_index, selection_name):
155
    # XXX FIXME can catch to many exceptions
Jean-Paul Smets's avatar
Jean-Paul Smets committed
156
    try:
157 158 159
      if cname_id in ('getExplanationText','getExplanation', ):
        o = self.getObject()
        if o is not None:
160 161
          explanation = o.getExplanationValue()
          if explanation is not None:
162 163
            return '%s/%s' % (self.portal_url.getPortalObject().absolute_url(),
                              explanation.getRelativeUrl())
164 165
        else:
          return ''
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
        # XXX Coramy, to be deleted
#       elif cname_id in ('getAggregateList','getAggregateListText',):
#         kw = {
#            'list_method_id' : 'Resource_zGetAggregateList',
#            'explanation_uid' : self.explanation_uid,
#            'node_uid' : self.node_uid,
#            'section_uid' : self.section_uid,
#            'variation_text' : self.variation_text,
#            'resource_uid' : self.resource_uid,
#            'reset': 1
#         }
#         url_params_string = make_query(kw)
#         # should be search XXX
#         return '%s/piece_tissu?%s ' % (
#             self.portal_url.getPortalObject().absolute_url(),
#             url_params_string
#             )
      elif (self.resource_relative_url is not None):
        # A resource is defined, so try to display the movement list
        resource = self.portal_categories.unrestrictedTraverse(
                                self.resource_relative_url)
        form_name = 'Resource_viewMovementHistory'
        query_kw = {
          'variation_text': self.variation_text, 
          'selection_name': selection_name,
          'selection_index': selection_index,
        }
        # Add parameters to query_kw
        query_kw_update = {}
        if cname_id in ('getCurrentInventory', ):
          query_kw_update = {
            'simulation_state': list(self.getPortalCurrentInventoryStateList())
          }
        elif cname_id in ('getAvailableInventory', ):
          query_kw_update = {
            'omit_simulation': 1, 
            'omit_input': 1,
            'simulation_state': \
              list(self.getPortalReservedInventoryStateList())
          }
        elif cname_id in ('getFutureInventory', 'inventory', ):
          query_kw_update = {
            'simulation_state': \
              list(self.getPortalFutureInventoryStateList()) + \
              list(self.getPortalReservedInventoryStateList())
          }
        elif cname_id in ('getInventoryAtDate', ):
          query_kw_update = {
            'to_date': self.at_date,
            'simulation_state': \
              list(self.getPortalFutureInventoryStateList()) + \
              list(self.getPortalReservedInventoryStateList())
          }
        query_kw.update(query_kw_update)
        # Return result
        return '%s/%s?%s&reset=1' % (
          resource.absolute_url(),
          form_name,
          make_query(**query_kw))
Yoshinori Okuji's avatar
Yoshinori Okuji committed
225
    except (AttributeError, KeyError):
Jean-Paul Smets's avatar
Jean-Paul Smets committed
226 227
      return ''

228 229
  def getAggregateListText(self):
    aggregate_list = self.Resource_zGetAggregateList(
Jean-Paul Smets's avatar
Jean-Paul Smets committed
230 231 232 233 234 235 236 237
                                   explanation_uid = self.explanation_uid,
                                   node_uid = self.node_uid,
                                   section_uid = self.section_uid,
                                   variation_text = self.variation_text,
                                   resource_uid = self.resource_uid)
    result = []
    for o in aggregate_list:
      result.append(o.relative_url)
238
    return '<br>'.join(result)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
239

240 241 242
  def getExplanationText(self):
    # Returns an explanation of the movement
    o = self.getObject()
243
    explanation_text = 'Unknow'
244
    if o is not None:
245 246 247 248 249 250 251 252 253 254 255
      # Get the delivery/order
      delivery = o.getExplanationValue()
      if delivery is not None:
        explanation_text = "%s %s" % (delivery.getPortalType(),
                                      delivery.getTitleOrId())
        causality = delivery.getCausalityValue()
        if causality is not None:
          explanation_text = "%s (%s %s)" % (explanation_text,
                                             causality.getPortalType(),
                                             causality.getTitleOrId())
    return explanation_text
256

Jean-Paul Smets's avatar
Jean-Paul Smets committed
257 258 259 260 261 262 263 264 265
class DeliveryListBrain(InventoryListBrain):
  """
    Lists each variation
  """

  # Stock management
  def getInventory(self, at_date = None, ignore_variation=0, simulation_state=None, **kw):
    if type(simulation_state) is type('a'):
      simulation_state = [simulation_state]
Jean-Paul Smets's avatar
Jean-Paul Smets committed
266 267
    if hasattr(self, 'where_expression'):
      where_expression = self.where_expression
Jean-Paul Smets's avatar
Jean-Paul Smets committed
268
    else:
Jean-Paul Smets's avatar
Jean-Paul Smets committed
269
      where_expression = None
Jean-Paul Smets's avatar
Jean-Paul Smets committed
270 271
    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
                                          to_date=at_date,
272
                                          section_category = self.getPortalDefaultSectionCategory(),
Jean-Paul Smets's avatar
Jean-Paul Smets committed
273 274
                                          variation_text = self.variation_text,
                                          simulation_state = simulation_state,
Jean-Paul Smets's avatar
Jean-Paul Smets committed
275
                                          where_expression = where_expression)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
    inventory = None
    if len(result) > 0:
      inventory = result[0].inventory
    if inventory is None:
      return 0.0
    else:
      return inventory

  def getAvailableInventory(self):
    """
      Returns current inventory at current date
    """
    at_date=DateTime()
    current = self.getCurrentInventory()
    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
291
                                          omit_simulation = 1, omit_input = 1,
292
                                          section_category = self.getPortalDefaultSectionCategory(),
Jean-Paul Smets's avatar
Jean-Paul Smets committed
293
                                          variation_text = self.variation_text,
294
                                          simulation_state = self.getPortalReservedInventoryStateList())
Jean-Paul Smets's avatar
Jean-Paul Smets committed
295 296 297 298 299
    reserved_inventory = None
    if len(result) > 0:
      reserved_inventory = result[0].inventory
    if reserved_inventory is None:
      reserved_inventory = 0.0
300 301
    return current + reserved_inventory

302
  def getInventoryAtDate(self):
Jean-Paul Smets's avatar
Jean-Paul Smets committed
303
    """
304
      Returns inventory at the date provided by the SQL method
Jean-Paul Smets's avatar
Jean-Paul Smets committed
305 306
    """
    at_date=self.at_date
307
    LOG("At Date",0,str(at_date))
308
    return self.getInventory(at_date=at_date, ignore_variation=0, simulation_state=list(self.getPortalFutureInventoryStateList())+list(self.getPortalReservedInventoryStateList())+list(self.getPortalCurrentInventoryStateList()))
Jean-Paul Smets's avatar
Jean-Paul Smets committed
309