Subversion Repositories SmartDukaan

Rev

Rev 4739 | Rev 5065 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
626 chandransh 1
#!/usr/bin/python
4090 chandransh 2
'''
3
This script is used to load item details in the catalog database.
4
It's now mostly used for Accessories since they come in huge numbers.
1080 chandransh 5
 
4090 chandransh 6
@author: Chandranshu
7
'''
626 chandransh 8
import optparse
1080 chandransh 9
import csv
626 chandransh 10
import xlrd
11
import datetime
12
 
13
if __name__ == '__main__' and __package__ is None:
14
    import sys
15
    import os
16
    sys.path.insert(0, os.getcwd())
17
 
18
from shop2020.thriftpy.model.v1.catalog.ttypes import status
19
from shop2020.model.v1.catalog.impl import DataService
724 chandransh 20
from shop2020.model.v1.catalog.impl.DataService import Item, EntityIDGenerator,\
1356 chandransh 21
    ItemChangeLog, Vendor, VendorItemPricing, VendorItemMapping
626 chandransh 22
from elixir import *
23
 
4762 phani.kuma 24
def load_item_data(filename, vendorId, full_update, dry_run, supplied_product_group):
1250 chandransh 25
    DataService.initialize('catalog')
1356 chandransh 26
 
27
    vendor = Vendor.get_by(id=vendorId)
28
    if vendor is None:
29
        raise Exception("No vendor found for the id: " + str(vendorId))
626 chandransh 30
 
31
    workbook = xlrd.open_workbook(filename)
32
    sheet = workbook.sheet_by_index(0)
33
    num_rows = sheet.nrows
34
    updatedOn = datetime.datetime.now()
1080 chandransh 35
    new_items = []
1264 chandransh 36
    updated_items = []
4717 phani.kuma 37
    not_created_items = []
1356 chandransh 38
 
4762 phani.kuma 39
    existing_vendor_item_mappings = VendorItemMapping.query.filter_by(vendor=vendor).all()
1356 chandransh 40
    existing_vendor_item_mappings_set = set([mapping.item_key for mapping in existing_vendor_item_mappings])
41
 
626 chandransh 42
    for rownum in range(1, num_rows):
1833 chandransh 43
        print sheet.row_values(rownum)
1264 chandransh 44
 
1833 chandransh 45
        if supplied_product_group != None and supplied_product_group != '':
4739 phani.kuma 46
            our_brand, our_model_number, our_model_name, our_color,\
1810 chandransh 47
            brand, model_number, model_name, color,\
4739 phani.kuma 48
            dp, mrp, mop, sp, xfer_price,\
49
            comments, weight, start_date, deal_text, deal_value,\
4762 phani.kuma 50
            warranty_period, defaultWarehouse, preferredWarehouse, preferredVendor = sheet.row_values(rownum)[0:22]
1810 chandransh 51
            product_group = supplied_product_group
52
        else:
4739 phani.kuma 53
            our_brand, our_model_number, our_model_name, our_color,\
1810 chandransh 54
            product_group, brand, model_number, model_name, color,\
4739 phani.kuma 55
            dp, mrp, mop, sp, xfer_price,\
56
            comments, weight, start_date, deal_text, deal_value,\
4762 phani.kuma 57
            warranty_period, defaultWarehouse, preferredWarehouse, preferredVendor = sheet.row_values(rownum)[0:23]
1810 chandransh 58
 
1833 chandransh 59
        print product_group
60
 
626 chandransh 61
        if isinstance(model_number, float):
62
            model_number = str(int(model_number))
1810 chandransh 63
 
64
        if our_brand == '':
65
            our_brand = brand
66
        if our_model_number == '':
67
            our_model_number = model_number
4739 phani.kuma 68
        if our_model_name == '':
69
            our_model_name = model_name
1810 chandransh 70
        if our_color == '':
71
            our_color = color
72
 
1633 chandransh 73
        if sp == '':
74
            sp = mop 
1356 chandransh 75
        item = None
4725 phani.kuma 76
        similar_item = None
1356 chandransh 77
        vendor_item_pricing = None
1080 chandransh 78
 
1356 chandransh 79
        key = product_group.strip().lower() + '|' + brand.strip().lower() + '|' + model_number.strip().lower() + '|' + color.strip().lower()
80
        if key in existing_vendor_item_mappings_set:
81
            existing_vendor_item_mappings_set.remove(key)
82
 
4717 phani.kuma 83
        # Check if a similar items already exists in our database
4739 phani.kuma 84
        similar_items = Item.query.filter_by(brand=our_brand.strip(), model_number=our_model_number.strip(), model_name=our_model_name.strip()).all()
4717 phani.kuma 85
 
4725 phani.kuma 86
        # Check if a similar item already exists in our database
4717 phani.kuma 87
        for old_item in similar_items:
4725 phani.kuma 88
            if old_item.color != None and old_item.color.strip().lower() == our_color.strip().lower():
4717 phani.kuma 89
                item = old_item
90
                break
91
 
4725 phani.kuma 92
        # Check if a similar item already exists in our database with out valid color if similar item with same color is not found
626 chandransh 93
        if item is None:
4717 phani.kuma 94
            for old_item in similar_items:
4725 phani.kuma 95
                if not check_color_valid(old_item.color):
4717 phani.kuma 96
                    item = old_item
97
                    break
98
 
99
        i = 0
100
        color_of_similar_item = None
4725 phani.kuma 101
        # Check if a similar item already exists in our database to be used to get catalog_item_id
4717 phani.kuma 102
        for old_item in similar_items:
4725 phani.kuma 103
            # get a similar item already existing in our database with valid color
104
            if check_color_valid(old_item.color):
4717 phani.kuma 105
                similar_item = old_item
106
                color_of_similar_item = similar_item.color
107
                break
108
            i = i + 1
4725 phani.kuma 109
            # get a similar item already existing in our database if similar item with valid color is not found
4717 phani.kuma 110
            if i == len(similar_items):
111
                similar_item = old_item
112
                color_of_similar_item = similar_item.color
4725 phani.kuma 113
 
114
        # Check if a similar item that is obtained above is having a valid color
115
        if check_color_valid(color_of_similar_item):
116
            # if a similar item that is obtained above is having a valid color and new item is about to be created with out valid color it is not done.
117
            # since for example if their is a item with red color in our database and we are creating a new item with no color for the same product which is wrong.
118
            if item is None and not check_color_valid(our_color):
4717 phani.kuma 119
                not_created_items.append(rownum)
120
                continue
121
 
122
 
123
        if item is None:
124
            #print "[ADDING:]{0} {1} {2} {3} to our catalogue.".format(brand, model_number, model_name, color)
1080 chandransh 125
            new_items.append(rownum)
626 chandransh 126
            item = Item()
4762 phani.kuma 127
            item.brand = our_brand.strip()
4717 phani.kuma 128
            item.product_group = product_group.strip()
129
            item.model_number = our_model_number.strip()
4739 phani.kuma 130
            item.model_name = our_model_name.strip()
4717 phani.kuma 131
            item.color = our_color.strip()
626 chandransh 132
            item.status = status.IN_PROCESS
2035 rajveer 133
            item.status_description = "This item is in process"
626 chandransh 134
            item.addedOn = updatedOn
1356 chandransh 135
 
4762 phani.kuma 136
            vendor_item_mapping = VendorItemMapping(vendor=vendor, item=item, item_key=key)
1359 chandransh 137
            vendor_item_pricing = VendorItemPricing(vendor=vendor, item=item)
138
 
626 chandransh 139
            session.add(item)
1356 chandransh 140
            session.add(vendor_item_mapping)
1359 chandransh 141
            session.add(vendor_item_pricing)
1080 chandransh 142
 
4717 phani.kuma 143
            if similar_item is None or similar_item.catalog_item_id is None:
144
                # If there is no similar item in the database from before,
145
                # use the entity_id_generator
146
                entity_id = EntityIDGenerator.query.first()
147
                item.catalog_item_id = entity_id.id + 1
148
                entity_id.id = entity_id.id  + 1
149
                if similar_item is not None and similar_item.catalog_item_id is None:
150
                    similar_item.catalog_item_id = entity_id.id
1080 chandransh 151
            else:
4717 phani.kuma 152
                #If a similar item already exists for a product group, brand and model_number, set it as same.
153
                item.catalog_item_id = similar_item.catalog_item_id
154
                item.category = similar_item.category
4762 phani.kuma 155
                item.product_group = similar_item.product_group
4717 phani.kuma 156
                item.status = similar_item.status
157
                item.status_description = similar_item.status_description
158
                #Use the same brand, model name and model number as in similar item in database
159
                item.brand = similar_item.brand
160
                item.model_name = similar_item.model_name
161
                item.model_number = similar_item.model_number
626 chandransh 162
        else:
1356 chandransh 163
            # If this item already existed and one of its price parameters has changed
1278 chandransh 164
            # in which case we add it to the list of updated items for reporting.
1965 chandransh 165
            if item.status == status.PHASED_OUT:
166
                item.status = status.IN_PROCESS #Not the ideal choice but we don't know whether content has been generated for it beforehand.
2035 rajveer 167
                item.status_description = "This item is in process"
4717 phani.kuma 168
 
4725 phani.kuma 169
            if check_color_valid(our_color) and (item.color == None or item.color.strip().lower() != our_color.strip().lower()):
4717 phani.kuma 170
                item.color = our_color.strip()
171
 
172
            vendor_item_mapping = VendorItemMapping.get_by(vendor=vendor, item=item)
173
            if vendor_item_mapping is None:
4762 phani.kuma 174
                vendor_item_mapping = VendorItemMapping(vendor=vendor, item=item, item_key=key)
4717 phani.kuma 175
                session.add(vendor_item_mapping)
4725 phani.kuma 176
            else:
177
                vendor_item_mapping.item_key = key
178
 
1356 chandransh 179
            vendor_item_pricing = VendorItemPricing.get_by(vendor=vendor, item=item)
180
            if vendor_item_pricing is None:
181
                vendor_item_pricing = VendorItemPricing(vendor=vendor, item=item)
182
                session.add(vendor_item_pricing)
183
 
1633 chandransh 184
            if item.mrp != mrp or vendor_item_pricing.dealerPrice != dp or vendor_item_pricing.transfer_price != xfer_price or item.sellingPrice != sp:
4762 phani.kuma 185
                updated_items.append(sheet.row_values(rownum)[0:19] + [item.mrp, vendor_item_pricing.dealerPrice, vendor_item_pricing.transfer_price])
2330 rajveer 186
 
1080 chandransh 187
        if dp != "":
188
            item.sellingPrice = dp
1356 chandransh 189
            vendor_item_pricing.dealerPrice = dp
629 rajveer 190
 
1080 chandransh 191
        if mrp != "" and mop != "" and mrp <  mop:
4717 phani.kuma 192
            raise Exception("[BAD MRP and MOP:] for {0} {1} {2} {3}. MRP={4}. MOP={5}".format(brand, model_number, model_name, color, mrp, mop))
1080 chandransh 193
 
1633 chandransh 194
        if mrp != "" and sp != "" and mrp < sp:
4717 phani.kuma 195
            raise Exception("[BAD MRP and SP:] for {0} {1} {2} {3}. MRP={4}. SP={5}".format(brand, model_number, model_name, color, mrp, sp))
1633 chandransh 196
 
1080 chandransh 197
        if mop != "" and xfer_price != "" and xfer_price > mop:
4717 phani.kuma 198
            raise Exception("[BAD MOP and TP:] for {0} {1} {2} {3}. TP={4}. MOP={5}".format(brand, model_number, model_name, color, xfer_price, mop))
1320 chandransh 199
#        if mrp != "":
200
#            if item.mrp == None or item.mrp >= mrp:
201
#                item.mrp = mrp
202
#            else:
4717 phani.kuma 203
#                raise Exception("[NEW MRP MORE THAN old MRP:] for {0} {1} {2} {3}. Old mrp={4}. New MRP={5}".format(brand, model_number, model_name, color, item.mrp, mrp))
873 rajveer 204
 
4717 phani.kuma 205
        if defaultWarehouse == None or defaultWarehouse == "":
206
            raise Exception("[Default Warehouse required:] for {0} {1} {2} {3}".format(brand, model_number, model_name, color))
207
        else:
208
            try:
209
                item.defaultWarehouse = int(defaultWarehouse)
210
            except:
211
                raise Exception("[Default Warehouse should be number:] for {0} {1} {2} {3}. defaultWarehouse={4}".format(brand, model_number, model_name, color, defaultWarehouse))
212
 
213
        if preferredVendor == None or preferredVendor == "":
214
            raise Exception("[Preferred Vendor required:] for {0} {1} {2} {3}".format(brand, model_number, model_name, color))
215
        else:
216
            try:
217
                item.preferredVendor = int(preferredVendor)
218
            except:
219
                raise Exception("[Preferred Vendor should be number:] for {0} {1} {2} {3}. preferredVendor={4}".format(brand, model_number, model_name, color, preferredVendor))
220
 
221
        if warranty_period != "":
222
            try:
223
                item.warranty_period = int(warranty_period)
224
            except:
4762 phani.kuma 225
                pass
4717 phani.kuma 226
 
4762 phani.kuma 227
        if preferredWarehouse != "":
228
            try:
229
                item.preferredWarehouse = int(preferredWarehouse)
230
            except:
231
                pass
232
 
1431 chandransh 233
        if mrp != "":
234
            item.mrp = mrp
235
 
629 rajveer 236
        if mop != "":
1356 chandransh 237
            vendor_item_pricing.mop = mop
1080 chandransh 238
 
724 chandransh 239
        if xfer_price !="":
1356 chandransh 240
            vendor_item_pricing.transfer_price = xfer_price
1080 chandransh 241
 
2088 chandransh 242
        if start_date is not None and start_date != '':
243
            #If a start date has been specified, it takes precedence.
244
            item.startDate = datetime.datetime(*xlrd.xldate_as_tuple(start_date, workbook.datemode))
245
        elif item.startDate == None or item.startDate == '': 
246
            #If start date is not specified and item's start date is not set, set it to current time
1431 chandransh 247
            item.startDate = datetime.datetime.now()
1080 chandransh 248
 
1633 chandransh 249
        item.sellingPrice = sp
1080 chandransh 250
 
629 rajveer 251
        if weight != "":    
252
            item.weight = weight
1080 chandransh 253
 
254
#        item.bestDealText = deal_text
255
#        if deal_value != "":
256
#            item.bestDealValue = deal_value
257
#        item.comments = comments
258
 
626 chandransh 259
        item.updatedOn = updatedOn
724 chandransh 260
 
261
        item_change_log = ItemChangeLog()
262
        item_change_log.new_status = item.status
263
        item_change_log.timestamp = updatedOn
264
        item_change_log.item = item
1080 chandransh 265
 
266
        if not dry_run:
267
            session.commit()
268
 
4717 phani.kuma 269
    write_report("items_not_created_dueto_color.csv", not_created_items, sheet, False)
1264 chandransh 270
    write_report("new_items.csv", new_items, sheet, False)
271
    write_report("updated_items.csv", updated_items, sheet, True)
1356 chandransh 272
    phased_out_items = [key.split('|') for key in list(existing_vendor_item_mappings_set)]
1264 chandransh 273
    write_report("phased_out_items.csv", phased_out_items, sheet, True)
1080 chandransh 274
 
275
    if (not dry_run) and full_update:
2035 rajveer 276
        query_string =  "UPDATE " + str(Item.table) + " SET status=" + str(status.PHASED_OUT) + ", status_description='This item has been phased out'" + ", updatedOn='"+ str(updatedOn) +"'"+\
4762 phani.kuma 277
                        " WHERE updatedOn <> '" + str(updatedOn) + "'";
1080 chandransh 278
        session.execute(query_string, mapper=Item)
626 chandransh 279
        session.commit()
280
 
281
    print "Successfully updated the item list information."
282
 
4725 phani.kuma 283
def check_color_valid(color):
284
    if color is not None:
285
        color = color.strip().lower()
286
        if color != '' and color != 'na' and color != 'blank' and color != '(blank)':
287
            return True
288
    return False
289
 
1264 chandransh 290
def write_report(filename, items, sheet, is_item):
4023 chandransh 291
    '''
292
    Iterates through the items list and writes all the values to the specified
293
    filename in the CSV format. 'is_item' indicates whether the list consists
294
    of row numbers or complete row data.
295
    '''
1080 chandransh 296
    items_writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_ALL)
1264 chandransh 297
    items_writer.writerow(sheet.row_values(0) + ['Old MRP', 'Old DP', 'Old TP'])
298
    if is_item:
4023 chandransh 299
        #The list contains the complete rows.
1264 chandransh 300
        for item in items:
1833 chandransh 301
            print item
1264 chandransh 302
            items_writer.writerow([str(value) for value in item])
303
    else:
4023 chandransh 304
        #The list only has row numbers. We've to fetch the data ourselves.
1264 chandransh 305
        for i in items:
1833 chandransh 306
            print sheet.row_values(i)
1264 chandransh 307
            items_writer.writerow([str(value) for value in sheet.row_values(i)])
1080 chandransh 308
 
626 chandransh 309
def main():
310
    parser = optparse.OptionParser()
311
    parser.add_option("-f", "--file", dest="filename",
312
                   default="ItemList.xls", type="string",
313
                   help="Read the item list from FILE",
314
                   metavar="FILE")
1356 chandransh 315
    parser.add_option("-v", "--vendor", dest="vendor",
316
                      type="int",
317
                      help="Update the pricing information for VENDOR",
318
                      metavar="VENDOR")
1080 chandransh 319
    parser.add_option("-d", "--dry-run", dest="dry_run",
320
                      action="store_true",
321
                      help="Dry run only reporting on pending changes.Please note that some of the items can be reported twice.")
322
    parser.add_option("-a", "--full", dest="full_update",
323
                      action="store_true",
324
                      help="In a full update, all older items are marked as PHASED_OUT. Also see -pm.")
325
    parser.add_option("-p", "--partial", dest="full_update",
326
                      action="store_false",
327
                      help="In a partial update, older items are left as is. Also see -fm.")
1356 chandransh 328
    parser.add_option("-g", "--product-group", dest="product_group",
329
                      type="string",
330
                      help="Set GROUP as the product group for all items added/updated during this run.",
331
                      metavar="GROUP")
4762 phani.kuma 332
    parser.set_defaults(full_update=True, dry_run=False, vendor=1)
626 chandransh 333
    (options, args) = parser.parse_args()
334
    if len(args) != 0:
335
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
336
    filename = options.filename
4762 phani.kuma 337
    load_item_data(filename, options.vendor, options.full_update, options.dry_run, options.product_group)
626 chandransh 338
 
339
if __name__ == '__main__':
340
    main()