Subversion Repositories SmartDukaan

Rev

Rev 2330 | Rev 4090 | 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
1080 chandransh 2
 
626 chandransh 3
import optparse
1080 chandransh 4
import csv
626 chandransh 5
import xlrd
6
import datetime
7
 
8
if __name__ == '__main__' and __package__ is None:
9
    import sys
10
    import os
11
    sys.path.insert(0, os.getcwd())
12
 
13
from shop2020.thriftpy.model.v1.catalog.ttypes import status
14
from shop2020.model.v1.catalog.impl import DataService
724 chandransh 15
from shop2020.model.v1.catalog.impl.DataService import Item, EntityIDGenerator,\
1356 chandransh 16
    ItemChangeLog, Vendor, VendorItemPricing, VendorItemMapping
626 chandransh 17
from elixir import *
18
 
1810 chandransh 19
def load_item_data(filename, vendorId, category, full_update, dry_run, supplied_product_group):
1250 chandransh 20
    DataService.initialize('catalog')
1356 chandransh 21
 
22
    vendor = Vendor.get_by(id=vendorId)
23
    if vendor is None:
24
        raise Exception("No vendor found for the id: " + str(vendorId))
626 chandransh 25
 
26
    workbook = xlrd.open_workbook(filename)
27
    sheet = workbook.sheet_by_index(0)
28
    num_rows = sheet.nrows
29
    updatedOn = datetime.datetime.now()
1080 chandransh 30
    new_items = []
1264 chandransh 31
    updated_items = []
1356 chandransh 32
 
33
    existing_vendor_item_mappings = VendorItemMapping.query.filter_by(vendor=vendor, vendor_category=category).all()
34
    existing_vendor_item_mappings_set = set([mapping.item_key for mapping in existing_vendor_item_mappings])
35
 
626 chandransh 36
    for rownum in range(1, num_rows):
1833 chandransh 37
        print sheet.row_values(rownum)
1356 chandransh 38
        catalog_item_id, category_id = [None, None]
1264 chandransh 39
 
1833 chandransh 40
        if supplied_product_group != None and supplied_product_group != '':
1810 chandransh 41
            our_brand, our_model_number, our_color,\
42
            brand, model_number, model_name, color,\
43
            dp, mrp, mop, sp,\
44
            comments, hotspot_category, unused_feature, xfer_price, weight, start_date, deal_text, deal_value = sheet.row_values(rownum)[0:19]
45
            product_group = supplied_product_group
46
        else:
47
            our_brand, our_model_number, our_color,\
48
            product_group, brand, model_number, model_name, color,\
49
            dp, mrp, mop, sp,\
50
            comments, hotspot_category, unused_feature, xfer_price, weight, start_date, deal_text, deal_value = sheet.row_values(rownum)[0:20]
51
 
1833 chandransh 52
        print product_group
53
 
626 chandransh 54
        if isinstance(model_number, float):
55
            model_number = str(int(model_number))
1810 chandransh 56
 
57
        if our_brand == '':
58
            our_brand = brand
59
        if our_model_number == '':
60
            our_model_number = model_number
61
        if our_color == '':
62
            our_color = color
63
 
1633 chandransh 64
        if sp == '':
65
            sp = mop 
1356 chandransh 66
        item = None
67
        vendor_item_pricing = None
1080 chandransh 68
 
1356 chandransh 69
        key = product_group.strip().lower() + '|' + brand.strip().lower() + '|' + model_number.strip().lower() + '|' + color.strip().lower()
70
        if key in existing_vendor_item_mappings_set:
71
            existing_vendor_item_mappings_set.remove(key)
72
            item = VendorItemMapping.query.filter_by(vendor=vendor, item_key=key, vendor_category=category).one().item
73
 
626 chandransh 74
        if item is None:
1080 chandransh 75
            #print "[ADDING:]{0} {1} {2} {3} to our catalogue.".format(product_group, brand, model_number, color)
76
            new_items.append(rownum)
626 chandransh 77
            item = Item()
2330 rajveer 78
            item.product_group = product_group
79
            item.brand = our_brand
80
            item.model_number = our_model_number
81
            item.model_name = model_name
626 chandransh 82
            item.status = status.IN_PROCESS
2035 rajveer 83
            item.status_description = "This item is in process"
626 chandransh 84
            item.addedOn = updatedOn
1089 chandransh 85
            item.hotspotCategory = category
1356 chandransh 86
 
1506 chandransh 87
            if category == 'Handsets':
88
                item.preferredWarehouse = 1
89
            else:
90
                item.preferredWarehouse = 2
91
 
1356 chandransh 92
            vendor_item_mapping = VendorItemMapping(vendor=vendor, item=item, item_key=key, vendor_category=category)
1359 chandransh 93
            vendor_item_pricing = VendorItemPricing(vendor=vendor, item=item)
94
 
626 chandransh 95
            session.add(item)
1356 chandransh 96
            session.add(vendor_item_mapping)
1359 chandransh 97
            session.add(vendor_item_pricing)
1080 chandransh 98
 
99
            if catalog_item_id !=None and catalog_item_id != "":
100
                #Add category and entity id
101
                item.catalog_item_id = int(catalog_item_id)
102
                item.category = int(category_id)
103
                item.status = status.ACTIVE
2035 rajveer 104
                item.status_description = "This item is active"
1080 chandransh 105
            else:
106
                # Check if a similar item already exists in our database
1810 chandransh 107
                similar_item = Item.query.filter_by(product_group=product_group, brand = our_brand, model_number=our_model_number, hotspotCategory=category).first()
1356 chandransh 108
                print "[SIMILAR ITEM FOUND:] FOR {0} {1} {2} {3}".format(product_group, brand, model_number, color)
109
 
1080 chandransh 110
                if similar_item is None or similar_item.catalog_item_id is None:
111
                    # If there is no similar item in the database from before,
112
                    # use the entity_id_generator
113
                    entity_id = EntityIDGenerator.query.first()
114
                    item.catalog_item_id = entity_id.id + 1
115
                    entity_id.id = entity_id.id  + 1
2330 rajveer 116
 
117
 
1080 chandransh 118
                else:
119
                    #If a similar item already exists for a product group, brand and model_number, set it as same.
120
                    item.catalog_item_id = similar_item.catalog_item_id
121
                    item.category = similar_item.category
1356 chandransh 122
                    item.status = similar_item.status
2035 rajveer 123
                    item.status_description = similar_item.status_description
2330 rajveer 124
                    #Use the same brand, model name and model number as in similar item in database
125
                    item.brand = similar_item.brand
126
                    item.model_name = similar_item.model_name
127
                    item.model_number = similar_item.model_number
626 chandransh 128
        else:
1356 chandransh 129
            # If this item already existed and one of its price parameters has changed
1278 chandransh 130
            # in which case we add it to the list of updated items for reporting.
1965 chandransh 131
            if item.status == status.PHASED_OUT:
132
                item.status = status.IN_PROCESS #Not the ideal choice but we don't know whether content has been generated for it beforehand.
2035 rajveer 133
                item.status_description = "This item is in process"
1356 chandransh 134
            vendor_item_pricing = VendorItemPricing.get_by(vendor=vendor, item=item)
135
            if vendor_item_pricing is None:
136
                vendor_item_pricing = VendorItemPricing(vendor=vendor, item=item)
137
                session.add(vendor_item_pricing)
138
 
1633 chandransh 139
            if item.mrp != mrp or vendor_item_pricing.dealerPrice != dp or vendor_item_pricing.transfer_price != xfer_price or item.sellingPrice != sp:
140
                updated_items.append(sheet.row_values(rownum)[0:19] + [item.mrp, item.dealerPrice, item.transfer_price])
2330 rajveer 141
 
142
        #In future we will provide the option to edit color in CMS
1965 chandransh 143
        item.color = our_color
144
 
1080 chandransh 145
        if category_id !=None and category_id != "":
146
            item.category = int(category_id)
147
 
148
        if dp != "":
149
            item.dealerPrice = dp
150
            item.sellingPrice = dp
1356 chandransh 151
            vendor_item_pricing.dealerPrice = dp
629 rajveer 152
 
1080 chandransh 153
        if mrp != "" and mop != "" and mrp <  mop:
1271 chandransh 154
            raise Exception("[BAD MRP and MOP:] for {0} {1} {2} {3}. MRP={4}. MOP={5}".format(product_group, brand, model_number, color, mrp, mop))
1080 chandransh 155
 
1633 chandransh 156
        if mrp != "" and sp != "" and mrp < sp:
157
            raise Exception("[BAD MRP and SP:] for {0} {1} {2} {3}. MRP={4}. SP={5}".format(product_group, brand, model_number, color, mrp, sp))
158
 
1080 chandransh 159
        if mop != "" and xfer_price != "" and xfer_price > mop:
1271 chandransh 160
            raise Exception("[BAD MOP and TP:] for {0} {1} {2} {3}. TP={4}. MOP={5}".format(product_group, brand, model_number, color, xfer_price, mop))
1320 chandransh 161
#        if mrp != "":
162
#            if item.mrp == None or item.mrp >= mrp:
163
#                item.mrp = mrp
164
#            else:
165
#                raise Exception("[NEW MRP MORE THAN old MRP:] for {0} {1} {2} {3}. Old mrp={4}. New MRP={5}".format(product_group, brand, model_number, color, item.mrp, mrp))
873 rajveer 166
 
1431 chandransh 167
        if mrp != "":
168
            item.mrp = mrp
169
 
629 rajveer 170
        if mop != "":
171
            item.mop = mop
1356 chandransh 172
            vendor_item_pricing.mop = mop
1080 chandransh 173
 
724 chandransh 174
        if xfer_price !="":
175
            item.transfer_price = xfer_price
1356 chandransh 176
            vendor_item_pricing.transfer_price = xfer_price
1080 chandransh 177
 
2088 chandransh 178
        if start_date is not None and start_date != '':
179
            #If a start date has been specified, it takes precedence.
180
            item.startDate = datetime.datetime(*xlrd.xldate_as_tuple(start_date, workbook.datemode))
181
        elif item.startDate == None or item.startDate == '': 
182
            #If start date is not specified and item's start date is not set, set it to current time
1431 chandransh 183
            item.startDate = datetime.datetime.now()
1080 chandransh 184
 
1633 chandransh 185
        item.sellingPrice = sp
1080 chandransh 186
 
629 rajveer 187
        if weight != "":    
188
            item.weight = weight
1080 chandransh 189
 
190
#        item.bestDealText = deal_text
191
#        if deal_value != "":
192
#            item.bestDealValue = deal_value
193
#        item.comments = comments
194
 
626 chandransh 195
        item.updatedOn = updatedOn
724 chandransh 196
 
197
        item_change_log = ItemChangeLog()
198
        item_change_log.new_status = item.status
199
        item_change_log.timestamp = updatedOn
200
        item_change_log.item = item
1080 chandransh 201
 
202
        if not dry_run:
203
            session.commit()
204
 
1264 chandransh 205
    write_report("new_items.csv", new_items, sheet, False)
206
    write_report("updated_items.csv", updated_items, sheet, True)
1356 chandransh 207
    phased_out_items = [key.split('|') for key in list(existing_vendor_item_mappings_set)]
1264 chandransh 208
    write_report("phased_out_items.csv", phased_out_items, sheet, True)
1080 chandransh 209
 
210
    if (not dry_run) and full_update:
2035 rajveer 211
        query_string =  "UPDATE " + str(Item.table) + " SET status=" + str(status.PHASED_OUT) + ", status_description='This item has been phased out'" + ", updatedOn='"+ str(updatedOn) +"'"+\
1080 chandransh 212
                        " WHERE updatedOn <> '" + str(updatedOn) + "' AND hotspotCategory='" + category +"'";
213
        session.execute(query_string, mapper=Item)
626 chandransh 214
        session.commit()
215
 
216
    print "Successfully updated the item list information."
217
 
1264 chandransh 218
def write_report(filename, items, sheet, is_item):
4023 chandransh 219
    '''
220
    Iterates through the items list and writes all the values to the specified
221
    filename in the CSV format. 'is_item' indicates whether the list consists
222
    of row numbers or complete row data.
223
    '''
1080 chandransh 224
    items_writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_ALL)
1264 chandransh 225
    items_writer.writerow(sheet.row_values(0) + ['Old MRP', 'Old DP', 'Old TP'])
226
    if is_item:
4023 chandransh 227
        #The list contains the complete rows.
1264 chandransh 228
        for item in items:
1833 chandransh 229
            print item
1264 chandransh 230
            items_writer.writerow([str(value) for value in item])
231
    else:
4023 chandransh 232
        #The list only has row numbers. We've to fetch the data ourselves.
1264 chandransh 233
        for i in items:
1833 chandransh 234
            print sheet.row_values(i)
1264 chandransh 235
            items_writer.writerow([str(value) for value in sheet.row_values(i)])
1080 chandransh 236
 
626 chandransh 237
def main():
238
    parser = optparse.OptionParser()
239
    parser.add_option("-f", "--file", dest="filename",
240
                   default="ItemList.xls", type="string",
241
                   help="Read the item list from FILE",
242
                   metavar="FILE")
1080 chandransh 243
    parser.add_option("-c", "--category", dest="category",
244
                      type="string",
245
                      help="Update the list only for the products belonging to CATEGORY",
246
                      metavar="CATEGORY")
1356 chandransh 247
    parser.add_option("-v", "--vendor", dest="vendor",
248
                      type="int",
249
                      help="Update the pricing information for VENDOR",
250
                      metavar="VENDOR")
1080 chandransh 251
    parser.add_option("-d", "--dry-run", dest="dry_run",
252
                      action="store_true",
253
                      help="Dry run only reporting on pending changes.Please note that some of the items can be reported twice.")
254
    parser.add_option("-a", "--full", dest="full_update",
255
                      action="store_true",
256
                      help="In a full update, all older items are marked as PHASED_OUT. Also see -pm.")
257
    parser.add_option("-p", "--partial", dest="full_update",
258
                      action="store_false",
259
                      help="In a partial update, older items are left as is. Also see -fm.")
1356 chandransh 260
    parser.add_option("-g", "--product-group", dest="product_group",
261
                      type="string",
262
                      help="Set GROUP as the product group for all items added/updated during this run.",
263
                      metavar="GROUP")
264
    parser.set_defaults(full_update=True, dry_run=False, category="Handsets", vendor=1)
626 chandransh 265
    (options, args) = parser.parse_args()
266
    if len(args) != 0:
267
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
268
    filename = options.filename
1356 chandransh 269
    load_item_data(filename, options.vendor, options.category, options.full_update, options.dry_run, options.product_group)
626 chandransh 270
 
271
if __name__ == '__main__':
272
    main()