Subversion Repositories SmartDukaan

Rev

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