Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
6903 anupam.sin 1
# -*- coding: utf-8 -*-
2
 
104 ashish 3
'''
4
Created on 29-Mar-2010
5
 
2536 chandransh 6
@author: Chandranshu
104 ashish 7
'''
2536 chandransh 8
 
4369 rajveer 9
from datetime import date, timedelta
7151 amit.gupta 10
from decimal import Decimal
11
from elixir import *
6424 rajveer 12
from math import ceil
5944 mandeep.dh 13
from random import randrange
7151 amit.gupta 14
from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY
15
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
3499 mandeep.dh 16
from reportlab.lib.units import inch
2536 chandransh 17
from reportlab.pdfgen.canvas import Canvas
6980 anupam.sin 18
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, \
19
    BaseDocTemplate, Frame, PageTemplate
7151 amit.gupta 20
from reportlab.rl_config import defaultPageSize
5944 mandeep.dh 21
from shop2020.clients.AlertClient import AlertClient
3499 mandeep.dh 22
from shop2020.clients.CatalogClient import CatalogClient
23
from shop2020.clients.HelperClient import HelperClient
5944 mandeep.dh 24
from shop2020.clients.InventoryClient import InventoryClient
3499 mandeep.dh 25
from shop2020.clients.LogisticsClient import LogisticsClient
2747 chandransh 26
from shop2020.clients.PaymentClient import PaymentClient
7151 amit.gupta 27
from shop2020.clients.PromotionClient import PromotionClient
3499 mandeep.dh 28
from shop2020.clients.UserClient import UserClient
29
from shop2020.clients.WarehouseClient import WarehouseClient
7151 amit.gupta 30
from shop2020.config.client.ConfigClient import ConfigClient
7597 kshitij.so 31
#Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
32
from shop2020.clients.CRMClient import CRMClient
33
#End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
3499 mandeep.dh 34
from shop2020.model.v1 import order
6048 rajveer 35
from shop2020.model.v1.order.impl import DataService, RechargeService
7198 amar.kumar 36
from shop2020.model.v1.order.impl.Convertors import to_t_emi_scheme, to_t_order
3499 mandeep.dh 37
from shop2020.model.v1.order.impl.DataService import Transaction, LineItem, \
4435 mandeep.dh 38
    Order, BatchNoGenerator, InvoiceIDGenerator, TransactionRequiringExtraProcessing, \
5348 anupam.sin 39
    OrderInventory, Alert, PaymentSettlement, EBSSettlementSummary, \
7151 amit.gupta 40
    CodVerificationAgent, Attribute, RechargeVoucherTracker, EmiScheme, MiscCharges, \
41
    BlockedIpRange, DeniedIpAddress, InsuranceDetailForOrder, DocumentStore, \
42
    RechargeTransaction, HotspotStore, WalletForCompany, WalletHistoryForCompany, \
7311 kshitij.so 43
    FRC, OperatorSeries, SourceDetail, Company, \
7406 rajveer 44
    AmazonOrder, StoreOrderDetail, EdcBank, StoreOrderCollection
7151 amit.gupta 45
from shop2020.model.v1.order.impl.model.BaseOrder import BaseOrder
46
from shop2020.model.v1.order.impl.model.DTHRechargeOrder import DTHRechargeOrder
6000 mandeep.dh 47
from shop2020.model.v1.order.impl.model.MobileRechargeOrder import \
48
    MobileRechargeOrder
7151 amit.gupta 49
from shop2020.model.v1.order.impl.model.RechargeDenomination import \
50
    RechargeDenomination
51
from shop2020.model.v1.order.impl.model.RechargeOrder import RechargeOrder
52
from shop2020.model.v1.order.impl.model.RechargePlan import RechargePlan
2687 chandransh 53
from shop2020.model.v1.order.impl.model.ReturnOrder import ReturnOrder
7151 amit.gupta 54
from shop2020.model.v1.order.impl.model.ServiceAvailability import \
55
    ServiceAvailability
56
from shop2020.model.v1.order.impl.model.ServiceProvider import ServiceProvider
57
from shop2020.model.v1.order.impl.model.TelecomCircle import TelecomCircle
58
from shop2020.model.v1.order.impl.model.UserWallet import UserWallet
59
from shop2020.model.v1.order.impl.model.UserWalletHistory import \
60
    UserWalletHistory
5944 mandeep.dh 61
from shop2020.thriftpy.alert.ttypes import MonitoredEntity, EntityType
5527 anupam.sin 62
from shop2020.thriftpy.logistics.ttypes import DeliveryType, PickUpType
6000 mandeep.dh 63
from shop2020.thriftpy.model.v1.catalog.ttypes import ItemType
5944 mandeep.dh 64
from shop2020.thriftpy.model.v1.inventory.ttypes import BillingType, \
65
    InventoryServiceException, WarehouseType, InventoryType
4435 mandeep.dh 66
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
67
    TransactionStatus, OrderStatus, DelayReason, ExtraTransactionProcessingType, \
7151 amit.gupta 68
    HotspotAction, TimeoutSummary, OrderStatusGroups, OrderType, RechargeOrderStatus, \
7393 anupam.sin 69
    RechargeType, RechargeStatistics, DeviceNumberInfo, EmiChargeType, PayMethod, OrderSource,\
70
    StorePaymentStatus
5944 mandeep.dh 71
from shop2020.thriftpy.model.v1.user.ttypes import VoucherType
4421 mandeep.dh 72
from shop2020.thriftpy.payments.ttypes import PaymentException
7597 kshitij.so 73
#Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
74
from shop2020.thriftpy.crm.ttypes import *
75
#End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
5110 mandeep.dh 76
from shop2020.thriftpy.warehouse.ttypes import ScanType, \
77
    WarehouseServiceException
7406 rajveer 78
from shop2020.utils.EmailAttachmentSender import mail, get_attachment_part,\
79
    mail_html
855 rajveer 80
from shop2020.utils.Utils import to_py_date, to_java_date
4008 mandeep.dh 81
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
3499 mandeep.dh 82
from sqlalchemy.sql import func
7151 amit.gupta 83
from sqlalchemy.sql.expression import and_, or_, desc, not_, distinct, cast, \
84
    between
3499 mandeep.dh 85
from string import Template
86
from textwrap import dedent
87
import datetime
5944 mandeep.dh 88
import httplib
3499 mandeep.dh 89
import logging
90
import os
4421 mandeep.dh 91
import sys
4435 mandeep.dh 92
import time
4421 mandeep.dh 93
import traceback
5806 rajveer 94
import urllib
7308 rajveer 95
import base64
6307 anupam.sin 96
 
5944 mandeep.dh 97
 
3499 mandeep.dh 98
logging.basicConfig(level=logging.DEBUG)
104 ashish 99
 
5966 rajveer 100
sourceId = int(ConfigClient().get_property("sourceid"))
101
mail_user = 'cnc.center@shop2020.in'
102
mail_password = '5h0p2o2o'
103
help_user = 'help@shop2020.in'
104
help_password = '5h0p2o2o'
6029 rajveer 105
source_url = 'www.saholic.com'
106
source_name = 'Saholic'
3499 mandeep.dh 107
 
4763 rajveer 108
PREPAID_SHIPPING_CUTOFF_TIME = 15
4019 chandransh 109
COD_SHIPPING_CUTOFF_TIME = 12
3499 mandeep.dh 110
 
2819 chandransh 111
PAGE_HEIGHT=defaultPageSize[1]
112
PAGE_WIDTH=defaultPageSize[0]
113
 
4763 rajveer 114
billedOrdersColorMap = {}
115
 
3499 mandeep.dh 116
ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT = {
4873 mandeep.dh 117
        OrderStatus.RTO_RESHIPPED    :  3,
118
        OrderStatus.RTO_IN_TRANSIT   : -5,
119
        OrderStatus.DELIVERY_SUCCESS :  1,
120
        OrderStatus.DOA_CERT_INVALID : -5
3499 mandeep.dh 121
}
122
 
5783 rajveer 123
delhi_pincodes = ['110001','110002','110003','110004','110005','110006','110007','110008','110009','110010','110011','110012','110013','110014','110015',\
124
                '110016','110017','110018','110019','110020','110021','110022','110023','110024','110025','110026','110027','110028','110029','110030',\
125
                '110031','110032','110033','110034','110035','110037','110038','110041','110042','110044','110045','110046','110047','110048','110049',\
126
                '110051','110052','110053','110054','110055','110056','110057','110058','110059','110060','110061','110062','110063','110064','110065',\
127
                '110066','110067','110068','110070','110071','110074','110075','110076','110078','110081','110082','110083','110084','110085','110086',\
128
                '110087','110088','110089','110091','110092','110093','110094','110095','110096','110101','110103','110104','110105','110106','110107',\
129
                '110108','110109','110110','110112','110113','110114','110115','110116','110117','110118','110119','110120','110122','110124','110125',\
130
                '110301','110302','110501','110502','110503','110504','110505','110510','110511','110512','110601','110602','110603','110604','110605',\
131
                '110606','110607','110608','110609']
132
 
104 ashish 133
def get_new_transaction():
134
    transaction = Transaction()
135
    transaction.createdOn = datetime.datetime.now()
738 chandransh 136
    transaction.status = TransactionStatus.INIT
104 ashish 137
    transaction.status_message = "New transaction"
483 rajveer 138
    return transaction
139
 
140
def create_order(t_order):
141
    order = Order()
142
    if t_order.warehouse_id:
143
        order.warehouse_id = t_order.warehouse_id
509 rajveer 144
    if t_order.logistics_provider_id:    
483 rajveer 145
        order.logistics_provider_id = t_order.logistics_provider_id
146
        order.airwaybill_no = t_order.airwaybill_no
147
        order.tracking_id = t_order.tracking_id
4009 chandransh 148
    if t_order.expected_shipping_time:
4019 chandransh 149
        order.expected_shipping_time = to_py_date(t_order.expected_shipping_time).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 150
        order.promised_shipping_time = order.expected_shipping_time
4009 chandransh 151
    if t_order.expected_delivery_time:
483 rajveer 152
        order.expected_delivery_time = to_py_date(t_order.expected_delivery_time)
4102 chandransh 153
        order.promised_delivery_time = order.expected_delivery_time
483 rajveer 154
    if t_order.customer_id:    
155
        order.customer_id = t_order.customer_id
156
        order.customer_name = t_order.customer_name
860 rajveer 157
        order.customer_city = t_order.customer_city
158
        order.customer_state = t_order.customer_state
483 rajveer 159
        order.customer_mobilenumber = t_order.customer_mobilenumber
160
        order.customer_pincode = t_order.customer_pincode
738 chandransh 161
        order.customer_address1 = t_order.customer_address1
162
        order.customer_address2 = t_order.customer_address2
483 rajveer 163
        order.customer_email = t_order.customer_email
164
    #new status and status description to be added    
716 rajveer 165
    order.status = t_order.status  
483 rajveer 166
    order.statusDescription = t_order.statusDescription
167
    order.total_amount = t_order.total_amount
6318 rajveer 168
    order.gvAmount = t_order.gvAmount
483 rajveer 169
    order.total_weight = t_order.total_weight
170
    if t_order.created_timestamp:
171
        order.created_timestamp = to_py_date(t_order.created_timestamp)
172
    else:
685 chandransh 173
        order.created_timestamp = datetime.datetime.now()
5555 rajveer 174
    order.pickupStoreId = t_order.pickupStoreId
7033 anupam.sin 175
    if t_order.insurer:
176
        order.insurer = t_order.insurer
177
        order.insuranceAmount = t_order.insuranceAmount
6903 anupam.sin 178
    if order.insurer > 0:
179
        insuranceDetail = InsuranceDetailForOrder()
180
        insuranceDetail.dob = t_order.dob
181
        insuranceDetail.guardianName = t_order.guardianName
182
        insuranceDetail.order = order
7190 amar.kumar 183
    if t_order.freebieItemId:
184
        order.freebieItemId = t_order.freebieItemId
7293 anupam.sin 185
    order.source = t_order.source
186
    order.advanceAmount = t_order.advanceAmount
187
    order.storeId = t_order.storeId
483 rajveer 188
    return order
189
 
190
def create_transaction(t_transaction):
191
    t_orders = t_transaction.orders
192
    if not t_orders:
193
        raise TransactionServiceException(101, "Orders missing from the transaction")
194
    transaction = get_new_transaction()
195
    transaction.customer_id = t_transaction.customer_id 
196
    transaction.shopping_cart_id = t_transaction.shoppingCartid
2219 varun.gupt 197
    transaction.coupon_code = t_transaction.coupon_code
2815 vikas 198
    transaction.session_source = t_transaction.sessionSource
199
    transaction.session_start_time = to_py_date(t_transaction.sessionStartTime)
3858 vikas 200
    transaction.first_source = t_transaction.firstSource
201
    transaction.first_source_start_time = to_py_date(t_transaction.firstSourceTime)
483 rajveer 202
 
6389 rajveer 203
    totalAmount = 0
483 rajveer 204
    for t_order in t_orders:
205
        order = create_order(t_order)
6389 rajveer 206
        totalAmount = totalAmount + order.total_amount
483 rajveer 207
        order.transaction = transaction 
208
        for line_item in t_order.lineitems:
209
            litem = LineItem()
716 rajveer 210
            litem.item_id = line_item.item_id
963 chandransh 211
            litem.productGroup = line_item.productGroup
483 rajveer 212
            litem.brand = line_item.brand
213
            if line_item.model_number:
214
                litem.model_number = line_item.model_number
215
            if line_item.model_name:    
216
                litem.model_name = line_item.model_name
908 chandransh 217
            if line_item.color:
218
                litem.color = line_item.color
483 rajveer 219
            if line_item.extra_info:
220
                litem.extra_info = line_item.extra_info
221
            litem.quantity = line_item.quantity
222
            litem.unit_price = line_item.unit_price
223
            litem.unit_weight = line_item.unit_weight
224
            litem.total_price = line_item.total_price
225
            litem.total_weight = line_item.total_weight
4283 anupam.sin 226
            '''litem.transfer_price = line_item.transfer_price'''
4172 rajveer 227
            litem.dealText = line_item.dealText
4295 varun.gupt 228
            litem.warranty_expiry_timestamp = to_py_date(line_item.warrantry_expiry_timestamp)
1976 varun.gupt 229
 
483 rajveer 230
            """
231
            if line_item.addedOn:
232
                litem.added_on = to_py_date(line_item.addedOn)
233
            else:
234
                litem.added_on = datetime.datetime.now()
235
            """
236
            litem.order = order
237
    session.commit()
6389 rajveer 238
 
239
    generateOtherCharges(transaction, t_transaction.emiSchemeId, totalAmount)
240
 
483 rajveer 241
    return transaction.id
242
 
6389 rajveer 243
def generateOtherCharges(transaction, emiSchemeId, totalAmount):
244
    emiScheme = EmiScheme.get_by(id=emiSchemeId)
245
    if not emiScheme:
246
        return
247
 
248
    if totalAmount < emiScheme.minAmount:
249
        return
250
 
251
    emiCharge = 0
252
    if emiScheme.chargeType == EmiChargeType.FIXED:
6424 rajveer 253
        emiCharge = ceil(emiScheme.chargeValue)
6389 rajveer 254
    if emiScheme.chargeType == EmiChargeType.PERCENTAGE:
6424 rajveer 255
        emiCharge = ceil(totalAmount*(emiScheme.chargeValue)/100)
6736 amit.gupta 256
 
257
    if transaction.coupon_code is not None and transaction.coupon_code != "":    
258
        try:
259
            promotion_client = PromotionClient().get_client()
260
            emis = promotion_client.getEmiDiscount(transaction.shopping_cart_id)
261
            if emis.has_key(emiSchemeId):
262
                discount = emis.get(emiSchemeId)
263
                if emiCharge > discount:
264
                    emiCharge -= discount
265
                else:
266
                    emiCharge = 0
267
        except:
268
            print "Could not get emi discounts from promotion"
269
 
6389 rajveer 270
    miscCharge = MiscCharges()
271
    miscCharge.transaction = transaction
272
    miscCharge.chargeType = 1 ##EMI charges
273
    miscCharge.chargeAmount = emiCharge
274
    session.commit()
275
 
483 rajveer 276
def get_transaction(transaction_id):
277
    transaction = Transaction.get_by(id=transaction_id)
278
    if not transaction:
279
        raise TransactionServiceException(108, "no such transaction")
280
 
281
    return transaction
282
 
283
def get_transactions_for_customer(customer_id, from_date, to_date, status):
284
    if not customer_id:
285
        raise TransactionServiceException(101, "bad customer id")
286
    query = Transaction.query.filter(Transaction.customer_id == customer_id)
1493 vikas 287
    if status is not None:
483 rajveer 288
        query = query.filter(Transaction.status == status)
289
    if from_date:
290
        query = query.filter(Transaction.createdOn >from_date)
291
    if to_date:
292
        query = query.filter(Transaction.createdOn < to_date)
293
    return query.all()
294
 
295
def get_transactions_for_shopping_cart_id(shopping_cart_id):
296
    transactions = Transaction.query.filter_by(shopping_cart_id=shopping_cart_id).all()
297
    return transactions
298
 
299
def get_transaction_status(transaction_id):
300
    if not transaction_id:
301
        raise TransactionServiceException(101, "bad transaction id")
302
 
303
    transaction = get_transaction(transaction_id)
304
 
305
    return transaction.status
306
 
7293 anupam.sin 307
def change_transaction_status(transaction_id, new_status, description, pickUp, orderType, source):
483 rajveer 308
    transaction = get_transaction(transaction_id)
309
    transaction.status = new_status
310
    transaction.status_message = description
5783 rajveer 311
    ## Assign runner in case of delhi pincodes
5784 rajveer 312
    if transaction.orders[0].pickupStoreId:
313
        logistics_client = LogisticsClient().get_client() 
314
        store = logistics_client.getPickupStore(transaction.orders[0].pickupStoreId)
315
        if delhi_pincodes.__contains__(store.pin):
5793 rajveer 316
            pickUp = PickUpType.RUNNER  
5783 rajveer 317
 
690 chandransh 318
    if new_status == TransactionStatus.FAILED:
319
        for order in transaction.orders:
320
            order.status = OrderStatus.PAYMENT_FAILED
2339 chandransh 321
            order.statusDescription = "Payment Failed"
4247 rajveer 322
    elif new_status == TransactionStatus.AUTHORIZED or new_status == TransactionStatus.FLAGGED:
690 chandransh 323
        for order in transaction.orders:
4247 rajveer 324
            if new_status == TransactionStatus.AUTHORIZED:
325
                order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
326
                order.statusDescription = "Submitted to warehouse"
327
            elif new_status == TransactionStatus.FLAGGED:
328
                order.status = OrderStatus.PAYMENT_FLAGGED
329
                order.statusDescription = "Payment flagged by gateway"
3092 chandransh 330
            order.cod = False
5527 anupam.sin 331
            order.orderType = orderType
743 rajveer 332
            #After we got payment success, we will set logistics info also 
333
            logistics_client = LogisticsClient().get_client()
334
            #FIXME line item is only one now. If multiple will come, need to fix.
871 chandransh 335
            item_id = order.lineitems[0].item_id
5767 rajveer 336
            logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
743 rajveer 337
 
1730 ankur.sing 338
            current_time = datetime.datetime.now()
339
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 340
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 341
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
5110 mandeep.dh 342
 
6525 rajveer 343
            order.otg = logistics_info.otgAvailable
743 rajveer 344
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 345
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
743 rajveer 346
            order.logistics_provider_id = logistics_info.providerId
347
            order.airwaybill_no = logistics_info.airway_billno
348
            order.tracking_id = order.airwaybill_no
6726 rajveer 349
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 350
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 351
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 352
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 353
            order.promised_delivery_time = order.expected_delivery_time 
871 chandransh 354
 
6718 rajveer 355
            if order.pickupStoreId:
356
                order.otg = False
357
 
5944 mandeep.dh 358
            inventory_client = InventoryClient().get_client()
5966 rajveer 359
            inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
1351 varun.gupt 360
 
4316 anupam.sin 361
            try:
5944 mandeep.dh 362
                item_pricing = inventory_client.getItemPricing(item_id, -1)
4316 anupam.sin 363
                order.lineitems[0].transfer_price = item_pricing.transferPrice
6751 amar.kumar 364
                order.lineitems[0].nlc = item_pricing.nlc
4316 anupam.sin 365
            except:
366
                print "Not able to get transfer price. Skipping"
5944 mandeep.dh 367
 
368
            catalog_client = CatalogClient().get_client() 
5508 rajveer 369
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
370
            if voucherAmount:
5514 rajveer 371
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
7486 rajveer 372
            #Note 2 Buy back Offer
373
            if item_id in (7974, 7558) and transaction.coupon_code is not None and transaction.coupon_code.lower() == "note2buyback":    
374
                order.status = OrderStatus.COD_VERIFICATION_PENDING
375
                order.statusDescription = "Note 2 Buy Back Offer - Approval Pending from CRM Team"
7488 rajveer 376
                order.otg = False
5508 rajveer 377
 
3064 chandransh 378
    elif new_status == TransactionStatus.COD_IN_PROCESS:
379
        for order in transaction.orders:
4662 rajveer 380
            order.status = OrderStatus.COD_VERIFICATION_PENDING
3064 chandransh 381
            order.statusDescription = "Verification Pending"
382
            order.cod = True
5527 anupam.sin 383
            order.orderType = orderType
3064 chandransh 384
            #After we got payment success, we will set logistics info also 
385
            logistics_client = LogisticsClient().get_client()
386
            #FIXME line item is only one now. If multiple will come, need to fix.
387
            item_id = order.lineitems[0].item_id
5555 rajveer 388
            if order.pickupStoreId:
5885 mandeep.dh 389
                # Need to send prepaid awb number for store pick up orders
390
                logistics_info = logistics_client.getLogisticsEstimation(item_id, order.customer_pincode, DeliveryType.COD)
391
                prepaid_logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
392
                logistics_info.airway_billno = prepaid_logistics_info.airway_billno
393
                logistics_info.providerId = prepaid_logistics_info.providerId
6525 rajveer 394
                # Will not provide OTG in pickup store
395
                order.otg = False
5555 rajveer 396
            else:
5767 rajveer 397
                logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.COD, pickUp)
6525 rajveer 398
                order.otg = logistics_info.otgAvailable
7293 anupam.sin 399
 
3064 chandransh 400
            current_time = datetime.datetime.now()
401
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 402
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 403
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
404
 
3064 chandransh 405
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 406
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
3064 chandransh 407
            order.logistics_provider_id = logistics_info.providerId
408
            order.airwaybill_no = logistics_info.airway_billno
409
            order.tracking_id = order.airwaybill_no
6726 rajveer 410
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 411
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 412
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 413
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 414
            order.promised_delivery_time = order.expected_delivery_time
3064 chandransh 415
 
5944 mandeep.dh 416
            inventory_client = InventoryClient().get_client()
5966 rajveer 417
            inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
3064 chandransh 418
 
4316 anupam.sin 419
            try:
5944 mandeep.dh 420
                item_pricing = inventory_client.getItemPricing(item_id, -1)
6751 amar.kumar 421
                order.lineitems[0].transfer_price = item_pricing.transferPrice
422
                order.lineitems[0].nlc = item_pricing.nlc        
4316 anupam.sin 423
            except:
424
                print "Not able to get transfer price. Skipping"
5508 rajveer 425
 
5944 mandeep.dh 426
            catalog_client = CatalogClient().get_client()
5508 rajveer 427
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
428
            if voucherAmount:
5514 rajveer 429
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
7486 rajveer 430
 
431
            #Note 2 Buy back Offer    
432
            if item_id in (7974, 7558) and transaction.coupon_code is not None and transaction.coupon_code.lower() == "note2buyback":    
433
                order.status = OrderStatus.COD_VERIFICATION_PENDING
434
                order.statusDescription = "Note 2 Buy Back Offer - Approval Pending from CRM Team"
7488 rajveer 435
                order.otg = False
436
 
483 rajveer 437
    session.commit()
3499 mandeep.dh 438
 
7551 rajveer 439
    if new_status in (TransactionStatus.AUTHORIZED, TransactionStatus.FLAGGED, TransactionStatus.COD_IN_PROCESS):
440
        try:
441
            if order.source == OrderSource.WEBSITE:    
442
                if new_status == TransactionStatus.COD_IN_PROCESS:
443
                    transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
444
                    transaction_requiring_extra_processing.category = 'COD_VERIFICATION'
445
                    transaction_requiring_extra_processing.transaction_id = transaction_id
7344 rajveer 446
                    session.commit()
7551 rajveer 447
                elif new_status == TransactionStatus.FLAGGED:
448
                    transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
449
                    transaction_requiring_extra_processing.category = 'PAYMENT_FLAGGED'
450
                    transaction_requiring_extra_processing.transaction_id = transaction_id
7344 rajveer 451
                    session.commit()
7551 rajveer 452
            elif order.source == OrderSource.STORE:
7557 rajveer 453
                order.otg = False
454
                session.commit()
455
                catalog_client = CatalogClient().get_client() 
456
                sourcePricing = catalog_client.getStorePricing(order.lineitems[0].item_id)
457
                if order.total_amount >= sourcePricing.minPrice:
458
                    order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
459
                    order.statusDescription = "Order Accepted"
7551 rajveer 460
                    session.commit()
7557 rajveer 461
                    sod = StoreOrderDetail.get_by(orderId = order.id)
462
                    __push_store_collection_to_hotspot(order, "advance", sod.cashAmount, sod.cardAmount)
463
 
464
                else: 
465
                    order.status = OrderStatus.COD_VERIFICATION_PENDING
466
                    order.statusDescription = "Approval Pending"
467
                    content = "<html><body>"
468
                    content += "<h4>Order Id:  " + str(order.id) + "</h4>"
469
                    content += "<h4>Product:  " + str(order.lineitems[0]) + "</h4>"
470
                    content += "<h4>Min Price: " +  str(sourcePricing.minPrice) + "</h4>"
471
                    content += "<h4>Recommended Price: " +  str(sourcePricing.recommendedPrice) + "</h4>"
472
                    content += "<h2>Approval Requested for Price: " +  str(order.total_amount) + "</h2>"
473
                    content += "<h2>Note 1: If this discount price is approved then reply 'Approved' otherwise 'Not Approved' without changing anythig in the Mail.</h2>"  
474
                    content += "<h2>Note 2: For Quick approval using browser <a href='http://support.shop2020.in:8080/Support/price-approval?xszbg=" + base64.b64encode(str(order.id))  + "'>Click Here</a></h2>"
475
                    content += "<br><br></body></html>"
476
                    store = get_hotspot_store(order.storeId, "")
477
                    helper_client = HelperClient().get_client()
478
                    helper_client.saveUserEmailForSending(store.approvalEmail.split(';'), "", "Price approval requested for " + str(order.lineitems[0]) + " order Id " + str(order.id) + " in store " + store.hotspotId , content, str(transaction_id), "PriceApproval", [], [])
479
                    session.commit()
480
            else:
481
                order.otg = False
7551 rajveer 482
        except Exception as e:
483
            print "Error inserting transaction Id: " + str(transaction_id) + " due to " + str(e)
3499 mandeep.dh 484
 
483 rajveer 485
    return True
486
 
5514 rajveer 487
def __create_recharge_voucher_tracker(order, amount, voucherType):
5508 rajveer 488
    rvt = RechargeVoucherTracker()
489
    rvt.order = order
490
    rvt.amount = amount
491
    rvt.voucherIssued = False
5514 rajveer 492
    rvt.voucherType = voucherType
5508 rajveer 493
 
3994 chandransh 494
def __get_holidays(start_time=0L, to_time=-1L):
495
    '''
496
    Get the list of all public holidays since start time including the
497
    day of start time if it's a holiday
498
    '''
499
    midnightTime = start_time.replace(hour=0, minute=0, second=0, microsecond=0)
1730 ankur.sing 500
    fromDate = to_java_date(midnightTime)
501
    logistics_client = LogisticsClient().get_client()
3994 chandransh 502
    #TODO: This list should be cached after the first call.
503
    #Calling logistics server is also unnecessary.
504
    holidays = logistics_client.getHolidays(fromDate, to_time)
505
    holidays = [to_py_date(holiday).date() for holiday in holidays]
506
    return holidays
507
 
508
def adjust_delivery_time(start_time, delivery_days):
509
    '''
510
    Returns the actual no. of days which will pass while 'delivery_days'
511
    no. of business days will pass since 'order_time'. 
512
    '''
513
    start_date = start_time.date()
514
    end_date = start_date + datetime.timedelta(days = delivery_days)
515
    holidays = __get_holidays(start_time)
1730 ankur.sing 516
 
3994 chandransh 517
    while start_date <= end_date:
518
        if start_date.weekday() == 6 or start_date in holidays:
1730 ankur.sing 519
            delivery_days = delivery_days + 1
3994 chandransh 520
            end_date = end_date + datetime.timedelta(days = 1)
4088 chandransh 521
        start_date = start_date + datetime.timedelta(days = 1)
3994 chandransh 522
 
1730 ankur.sing 523
    return delivery_days
524
 
7741 kshitij.so 525
 
526
def adjust_shipping_time(delivery_date, delay):
527
    shipping_date=delivery_date - datetime.timedelta(days = delay)
528
    holidays = __get_holidays(shipping_date)
529
    while(True):
530
        if shipping_date.weekday() == 6 or shipping_date in holidays:
531
            shipping_date = shipping_date - datetime.timedelta(days = 1)
532
        else:
533
            return shipping_date        
534
 
535
 
536
 
6561 amit.gupta 537
def get_business_days_count(start_time, end_time):
538
    '''
539
    Returns business dates between two dates
540
    '''
541
    start_date = start_time.date()
542
    end_date  = end_time.date()
6669 amit.gupta 543
    diff = (end_date - start_date).days
6665 amit.gupta 544
    sundays = diff/7 + 1 if (start_date.weekday() + (diff%7) > 6) else diff/7 
6561 amit.gupta 545
    '''holidays = __get_holidays(start_time, end_time)'''
546
    logistics_client = LogisticsClient().get_client()
547
    #TODO: This list should be cached after the first call.
548
    #Calling logistics server is also unnecessary.
549
    holidays = logistics_client.getHolidays(to_java_date(start_time), to_java_date(end_time))
550
    non_business_days = len(holidays)
551
    for holiday in holidays:
6675 rajveer 552
        pyholiday = to_py_date(holiday).date()
553
        if pyholiday.weekday() == 6:
6561 amit.gupta 554
            sundays = sundays - 1
555
    return diff - (non_business_days + sundays)
556
 
557
 
1398 varun.gupt 558
def enqueue_transaction_info_email(transaction_id):
1262 varun.gupt 559
    transaction = get_transaction(transaction_id)
6650 amit.gupta 560
    subject = source_name + " - Order Details"
7428 rajveer 561
    orders = transaction.orders
562
    advance_amount = orders[0].advanceAmount
563
    saddress = ""
7429 rajveer 564
    bcc = []
7428 rajveer 565
    if advance_amount  > 0:
7430 rajveer 566
        store = get_hotspot_store(orders[0].storeId, "")
567
        bcc = bcc + store.approvalEmail.split(';')  + [store.email,  "rajveer.singh@shop2020.in", "rajneesh.arora@shop2020.in", "anupam.singh@shop2020.in", "amit.sirohi@shop2020.in"]
568
        saddress += " at our store " + __get_hotspot_store_address_html(store)
6650 amit.gupta 569
    otgLink = ""
6660 amit.gupta 570
    inOrderOtg = "<div>On Time Guarantee<br><span style=color:red>We pay if we delay</span></div>"
6650 amit.gupta 571
    if len(transaction.orders) == 1:
572
        inOrderOtg = ""
573
        if transaction.orders[0].otg :
574
            subject = "Your Order is confirmed with On Time Guarantee We Pay if we Delay"
575
            otgLink = ' Your Order is covered under the <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee, We pay If we Delay.</a>'
576
 
5793 rajveer 577
    customer_name = "" 
1262 varun.gupt 578
    html_header = """
579
<html>
580
<body>
581
<div>
582
    <p>
5793 rajveer 583
        Hello $customer_name,<br /><br />
7428 rajveer 584
        Thanks for placing order with us $saddress .$otgLink Following are the details of your order:
1262 varun.gupt 585
    </p>
586
    <div>
587
        Order Date: $order_date
1569 varun.gupt 588
    </div>
1262 varun.gupt 589
    <div>
590
        <table>
5879 rajveer 591
        <tr><td colspan="6"><hr /></td></tr>
592
        <tr><td colspan="6" align="left"><b>Order Details</b></td></tr>
593
        <tr><td colspan="6"><hr /></td></tr>
1262 varun.gupt 594
        <tr>
2050 varun.gupt 595
            <th width="100">Order No.</th>
596
            <th>Product</th>
5879 rajveer 597
            <th width="100">Estimated Delivery Date</th>
2050 varun.gupt 598
            <th width="100">Quantity</th>
599
            <th width="100">Unit Price</th>
600
            <th width="100">Amount</th>
1262 varun.gupt 601
        </tr>
602
    """
1398 varun.gupt 603
    user_email = ""
1262 varun.gupt 604
    total_amount = 0.0
605
    html_table = ""
1569 varun.gupt 606
    order_date = datetime.datetime.now()
5676 rajveer 607
 
608
    html_pickup_text = ""
609
    random_text = ""
5697 rajveer 610
    if orders[0].pickupStoreId:
5793 rajveer 611
        random_text = str(randrange(100000, 999999)) 
6650 amit.gupta 612
 
6654 amit.gupta 613
    first = True    
5676 rajveer 614
    for order in orders:
5793 rajveer 615
        customer_name = order.customer_name
1262 varun.gupt 616
        order_date = order.created_timestamp
1398 varun.gupt 617
        user_email = order.customer_email
6654 amit.gupta 618
        if first:
619
            first = False
620
            html_tr = "" 
621
        else:
6659 amit.gupta 622
            html_tr =  "<tr><td colspan=6>&nbsp;</td></tr>"
6654 amit.gupta 623
        html_tr += "<tr><td align='center'>" + str(order.id) + "</td>"
5676 rajveer 624
 
5879 rajveer 625
        sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
626
        store_delivery_date = sdt.strftime("%d %B %Y")
627
 
5676 rajveer 628
        if order.pickupStoreId:
629
            attribute = Attribute()
630
            attribute.orderId = order.id
631
            attribute.name = "SECRET_CODE"
632
            attribute.value = random_text
633
            session.commit()
1262 varun.gupt 634
 
635
        for lineitem in order.lineitems:
2050 varun.gupt 636
            lineitem_total_price = round(lineitem.total_price, 2)
637
 
1276 chandransh 638
            html_tr += "<td>" + str(lineitem) + "</td>"
6561 amit.gupta 639
            if order.otg:
6650 amit.gupta 640
                html_tr += "<td align='center'><div>" + store_delivery_date + "</div>" + inOrderOtg + "</td>"
6561 amit.gupta 641
            else:
642
                html_tr += "<td align='center'>" + store_delivery_date + "</td>"
2050 varun.gupt 643
            html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
644
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
645
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
646
            total_amount += lineitem_total_price
1262 varun.gupt 647
            html_table += html_tr
7190 amar.kumar 648
        if order.freebieItemId:
649
            catalog_client = CatalogClient().get_client()
650
            item = catalog_client.getItem(order.freebieItemId)
7201 amar.kumar 651
            html_table += "<tr><td align='center'></td><td style='font-style:italic;' colspan='5'> Free Item: "+item.brand + " " + item.modelName + " " + item.modelNumber+"</td></tr>"
6906 rajveer 652
        if order.insurer:
653
            html_table += "<tr><td colspan=6>&nbsp;</td></tr>"
6927 rajveer 654
            html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a></td><td align='center'></td><td align='center'></td><td align='center'></td>"
6911 rajveer 655
            html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6927 rajveer 656
            total_amount += order.insuranceAmount
6422 rajveer 657
    emi_amount = 0
658
    miscCharges = get_misc_charges(transaction_id)
659
    if miscCharges.get(1):
660
        emi_amount = miscCharges.get(1)
661
 
1262 varun.gupt 662
    html_footer = """
5879 rajveer 663
        <tr><td colspan=6>&nbsp;</td></tr>
664
        <tr><td colspan=6><hr /></td></tr>
6422 rajveer 665
        """
666
    if emi_amount > 0:
6715 amit.gupta 667
        total_amount += emi_amount
6422 rajveer 668
        html_footer = html_footer + "<tr>\
669
                        <td colspan=5>EMI Processing Charges</td>\
670
                        <td> Rs. $emi_amount</td>\
671
                    </tr>"
7428 rajveer 672
 
7434 rajveer 673
    amount_string = "Total Amount"
7428 rajveer 674
    if advance_amount > 0:
7434 rajveer 675
        amount_string = "Balance Amount"
7428 rajveer 676
        total_amount -= advance_amount
677
        html_footer = html_footer + "<tr>\
678
                        <td colspan=5>Advance Paid</td>\
679
                        <td> Rs. $advance_amount</td>\
680
                    </tr>"
6422 rajveer 681
 
682
    html_footer = html_footer + "<tr>\
7434 rajveer 683
                <td colspan=5>$amount_string</td>\
6422 rajveer 684
                <td> Rs. $total_amount</td>\
685
                </tr>\
686
            </table>\
687
        </div>"
5793 rajveer 688
 
6422 rajveer 689
 
5793 rajveer 690
    store_address = ""
691
    if orders[0].pickupStoreId:
692
        store = LogisticsClient().get_client().getPickupStore(orders[0].pickupStoreId)
693
        store_address = __get_store_address_html(store)
694
 
695
        html_pickup_text = html_pickup_text + """
696
        <h3>Steps to Pickup In Store</h3>
5879 rajveer 697
        1) You will receive a confirmation email from us when your product(s) reaches the store. Once you receive the same, please visit the following store selected by you.<br>
5793 rajveer 698
        <br><i>$store_address</i><br>
699
        """
700
 
701
        if orders[0].cod:
702
            html_pickup_text = html_pickup_text + """
6318 rajveer 703
            2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
5793 rajveer 704
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
705
            <br>
6029 rajveer 706
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5793 rajveer 707
            </br><hr />
708
            """
709
        else:
710
            html_pickup_text = html_pickup_text + """
5879 rajveer 711
            2) Present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
5793 rajveer 712
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
713
            <br>
6029 rajveer 714
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5793 rajveer 715
            </br><hr />
716
            """
717
 
7428 rajveer 718
    html_store_cust_address = ""
719
    if advance_amount > 0:
720
        html_store_cust_address += "Your order shall be delivered at " + __get_order_address_html(orders[0]) 
721
    html_footer = html_footer + html_pickup_text + html_store_cust_address + """
1262 varun.gupt 722
    <p>
723
        Best Wishes,<br />
6029 rajveer 724
        $source_name Team
1262 varun.gupt 725
    </p>
726
</div>
727
</body>
728
</html>
729
    """
1398 varun.gupt 730
 
1569 varun.gupt 731
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
1565 varun.gupt 732
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
5793 rajveer 733
 
734
    sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
735
    store_delivery_date = sdt.strftime("%A, %d %B %Y")
736
 
7428 rajveer 737
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, source_url = source_url, otgLink = otgLink, saddress = saddress))
7434 rajveer 738
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, emi_amount = "%.2f" % emi_amount, advance_amount = "%.2f" % advance_amount, net_amount = "%.2f" % (total_amount-order.gvAmount), secret_code = random_text, store_address = store_address, store_delivery_date = store_delivery_date, source_url = source_url, source_name = source_name, amount_string = amount_string))
7429 rajveer 739
 
1351 varun.gupt 740
    try:
741
        helper_client = HelperClient().get_client()
7429 rajveer 742
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(transaction_id), "TransactionInfo", [], bcc)
5866 rajveer 743
 
1351 varun.gupt 744
        return True
745
    except Exception as e:
746
        print e
747
        return False
1262 varun.gupt 748
 
5802 rajveer 749
def enqueue_received_at_store_email(order):
750
    html_header = """
751
    <html>
752
    <body>
753
    <div>
754
        <p>
755
            Hello $customer_name,<br /><br />
756
            Your Product has reached the Store selected by you and is available for pickup. Please pick up your product on or before $order_expiry_date. Following are the details of your order and steps to pickup the same:
757
        </p>
758
        <div>
759
            Order Date: $order_date
760
        </div>
761
        <div>
762
            <table>
763
            <tr><td colspan="5"><hr /></td></tr>
764
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
765
            <tr><td colspan="5"><hr /></td></tr>
766
            <tr>
767
                <th width="100">Order No.</th>
768
                <th>Product</th>
769
                <th width="100">Quantity</th>
770
                <th width="100">Unit Price</th>
771
                <th width="100">Amount</th>
772
            </tr>
773
    """
774
    total_amount = 0.0
775
    html_table = ""
776
 
777
    html_pickup_text = ""
778
    random_text = __get_secret_code(order.id)
779
 
780
    customer_name = order.customer_name
781
    order_date = order.created_timestamp
782
    user_email = order.customer_email
783
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
784
 
785
    for lineitem in order.lineitems:
786
        lineitem_total_price = round(lineitem.total_price, 2)
787
 
788
        html_tr += "<td>" + str(lineitem) + "</td>"
789
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
790
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
791
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
792
        total_amount += lineitem_total_price
793
        html_table += html_tr
794
 
795
    html_footer = """
796
        <tr><td colspan=5>&nbsp;</td></tr>
797
        <tr><td colspan=5><hr /></td></tr>
798
        <tr>
799
            <td colspan=4>Total Amount</td>
800
            <td> Rs. $total_amount</td>
801
        </tr>
802
        </table>
803
    </div>
804
    """
805
 
806
    store_address = ""
807
    if order.pickupStoreId:
808
        store = LogisticsClient().get_client().getPickupStore(order.pickupStoreId)
809
        store_address = __get_store_address_html(store)
810
 
811
        html_pickup_text = html_pickup_text + """
812
        <h3>Steps to Pickup In Store</h3>
813
        1) Please visit the following store selected by you on or before $order_expiry_date<br>
814
        <br><i>$store_address</i><br>
815
        """
816
 
817
        if order.cod:
818
            html_pickup_text = html_pickup_text + """
6318 rajveer 819
            2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and quote your Secret Code <b><i>$secret_code</i></b> to claim your Product.<br><br>
5802 rajveer 820
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
821
            <br>
6029 rajveer 822
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5802 rajveer 823
            </br><hr />
824
            """
825
        else:
826
            html_pickup_text = html_pickup_text + """
827
            2) Present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
828
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
829
            <br>
6029 rajveer 830
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5802 rajveer 831
            </br><hr />
832
            """
833
 
834
        html_footer = html_footer + html_pickup_text + """
835
        <p>
836
            Best Wishes,<br />
6029 rajveer 837
            $source_name Team
5802 rajveer 838
        </p>
839
        </div>
840
        </body>
841
        </html>
842
        """
843
 
844
    subject = "Your order for " + str(order.lineitems[0]) + " is ready for Pickup in Store"
845
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
846
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
847
 
848
    oetd = datetime.datetime.now() + datetime.timedelta(days=4)
849
    formated_order_expiry_date = oetd.strftime("%A, %d %B %Y")
850
 
851
 
6029 rajveer 852
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))
6318 rajveer 853
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, net_amount = "%.2f" % (total_amount-order.netAmount), secret_code = random_text, store_address = store_address, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))
5802 rajveer 854
 
855
    try:
5812 rajveer 856
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6280 rajveer 857
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "ReceivedAtStore", [], [])
5802 rajveer 858
        return True
859
    except Exception as e:
860
        print e
861
        return False
862
 
5966 rajveer 863
def enqueue_delivery_success_mail(order):
5807 rajveer 864
    html_header = """
865
    <html>
866
    <body>
867
    <div>
868
        <p>
869
            Dear $customer_name,<br /><br />
870
    """
6561 amit.gupta 871
 
5807 rajveer 872
    if order.pickupStoreId:
873
        pickup_text = "Pickup Date: " + order.delivery_timestamp.strftime("%A, %d. %B %Y %I:%M%p")
874
        thank_you_html = """
875
        Thank you for shopping with us and picking up your order in Store. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers.<br><br>
876
 
6029 rajveer 877
        Following are the details of your order for which the pickup has happened. If you have not picked up this product please <a href="$source_url/contact-us" target="_blank">contact us</a> immediately.<br>
5807 rajveer 878
        """
879
    else:
880
        pickup_text = ""
6561 amit.gupta 881
        if order.otg:
882
 
883
            delayed = False
884
            fda = False
885
 
886
            if order.first_dlvyatmp_timestamp.date() < order.delivery_timestamp.date():
887
                fda = True
888
 
889
            fda_datetime = order.first_dlvyatmp_timestamp            
890
            fda_date = fda_datetime.date()
891
 
6711 amit.gupta 892
            if order.promised_delivery_time.date() < fda_date:
6561 amit.gupta 893
                delayed = True
894
 
895
            if not delayed and not fda:
896
                thank_you_html = """As Promised """ + str(order.lineitems[0]) +""" ordered by you has been <b>Delivered On Time.</b>""" 
897
            elif delayed:
898
                max_discount = 500
6711 amit.gupta 899
                delayedDays = get_business_days_count(order.promised_delivery_time, fda_datetime)
6561 amit.gupta 900
                max_discount = min(max_discount, order.lineitems[0].unit_price/10)
6686 anupam.sin 901
                discount = min(round(max_discount),delayedDays*50)  
6561 amit.gupta 902
                promotion_client = PromotionClient().get_client()
903
                endOn =  order.delivery_timestamp + datetime.timedelta(days = 30)
7347 amit.gupta 904
                expiry = endOn.strftime("%A, %d. %B %Y")
6561 amit.gupta 905
                endOn = to_java_date(endOn)
6688 anupam.sin 906
                arguments = "{\"endOn\":" + str(endOn) + ", \"emails\":[\"" + order.customer_email + "\"], \"couponType\":\"both\", \"usage_limit_for_user\":1, \"isCod\":False, \"discount\":" + str(discount) + "}"
6742 anupam.sin 907
                otgCoupon = promotion_client.createCoupon(28, '', arguments, False, "otg")
7347 amit.gupta 908
                thank_you_html = '$prodName ordered by you has been delivered. We apologise for a delay of $delayedDays business days.<br><br> As per our <b>On Time Guarantee</b> Please accept a Gift Voucher worth <b>Rs.$discount</b> as a token of our apology. <br><br>Your unique Gift Voucher Code is <b>$otgCoupon</b>. <br><br>You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.<br> Note:GV is valid till $expiry<br>'
909
                thank_you_html = Template(thank_you_html).substitute(dict(prodName=order.lineitems[0], delayedDays = delayedDays, discount = discount, otgCoupon = otgCoupon, expiry = expiry))
6561 amit.gupta 910
            elif fda:
911
                fdaFormattedString = order.first_dlvyatmp_timestamp.strftime("%A, %d. %B %Y")
912
                thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered.  The First Delivery attempt was made on """+ fdaFormattedString +""" , within our commited estimated time for delivery.""" 
913
 
914
            thank_you_html = thank_you_html + """If you are happy with our services please join us on <a href="http://www.facebook.com/mysaholic">Facebook</a>/<a href="https://twitter.com/saholic">Twitter</a> and help us spread the word."""  
915
 
916
        else :
917
            thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered. 
918
            Thank you for shopping with us. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers. Following are the details of your order.<br>
7198 amar.kumar 919
            """
920
 
921
    freebie_text = "<br/>"
922
    if order.freebieItemId:
923
        catalog_client = CatalogClient().get_client()
924
        item = catalog_client.getItem(order.freebieItemId)
925
        freebie_text = freebie_text = "We have also delivered " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised"
926
    else:
927
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
928
        if freebie_orderId != "":
929
            line_items = get_line_items_for_order(int(freebie_orderId))
930
            freebie_order = get_order(int(freebie_orderId))
7720 amar.kumar 931
            if order.cod:
932
                freebie_shipping_time = datetime.datetime.now() + datetime.timedelta(hours = 72)
933
                freebie_text = freebie_text + "We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be shipped by" + freebie_shipping_time.strftime("%A, %d. %B %Y") + "<br/>"
934
            else:
935
                freebie_text = freebie_text + " We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>You can track the status of this order from My Orders section in saholic.com" 
5807 rajveer 936
 
937
    html_header = html_header + thank_you_html + """        
938
        </p>
939
        <div>
940
            Order Date: $order_date <br>
941
            $pickup_text
942
        </div>
943
        <div>
944
            <table>
945
            <tr><td colspan="5"><hr /></td></tr>
946
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
947
            <tr><td colspan="5"><hr /></td></tr>
948
            <tr>
949
                <th width="100">Order No.</th>
950
                <th>Product</th>
951
                <th width="100">Quantity</th>
952
                <th width="100">Unit Price</th>
953
                <th width="100">Amount</th>
954
            </tr>
955
    """
956
    total_amount = 0.0
957
    html_table = ""
5802 rajveer 958
 
5807 rajveer 959
    customer_name = order.customer_name
960
    order_date = order.created_timestamp
961
    user_email = order.customer_email
962
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
963
 
964
    for lineitem in order.lineitems:
965
        lineitem_total_price = round(lineitem.total_price, 2)
966
 
967
        html_tr += "<td>" + str(lineitem) + "</td>"
968
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
969
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
970
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
971
        total_amount += lineitem_total_price
972
        html_table += html_tr
6906 rajveer 973
    if order.insurer:
6915 anupam.sin 974
        html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a></td><td align='center'></td><td align='center'></td>"
6911 rajveer 975
        html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6947 rajveer 976
        html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Please download and read attached policy document.</td><td align='center'></td><td align='center'></td></tr>"
6906 rajveer 977
        total_amount += order.insuranceAmount
978
 
5807 rajveer 979
    html_footer = """
980
        <tr><td colspan=5>&nbsp;</td></tr>
981
        <tr><td colspan=5><hr /></td></tr>
982
        <tr>
983
            <td colspan=4>Total Amount</td>
984
            <td> Rs. $total_amount</td>
985
        </tr>
986
        </table>
7198 amar.kumar 987
        $freebie_text
5807 rajveer 988
    </div>
989
    <p>
990
        Best Wishes,<br />
6029 rajveer 991
        $source_name Team
5807 rajveer 992
    </p>
993
    </div>
994
    </body>
995
    </html>
996
    """
997
 
998
    subject = "Your order for " + str(order.lineitems[0]) + " is now complete"
999
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
1000
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
1001
 
1002
 
6029 rajveer 1003
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, pickup_text = pickup_text, source_url = source_url))
7198 amar.kumar 1004
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, source_name = source_name, freebie_text = freebie_text))
5807 rajveer 1005
 
1006
    try:
5812 rajveer 1007
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6957 rajveer 1008
        if order.insurer:
1009
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], ["pramit.singh@shop2020.in ","anupam.singh@shop2020.in","rajveer.singh@shop2020.in"])
1010
        else:
1011
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], [])
5807 rajveer 1012
        return True
1013
    except Exception as e:
1014
        print e
1015
        return False
1016
 
5802 rajveer 1017
def __get_secret_code(order_id):
5855 rajveer 1018
    return get_order_attribute_value(order_id, 'SECRET_CODE')
5806 rajveer 1019
 
5833 rajveer 1020
def get_order_attribute_value(order_id, attribute_name):
5808 rajveer 1021
    existingAttribute = Attribute.query.filter(Attribute.orderId == order_id).filter(Attribute.name == attribute_name).first()
1022
    if existingAttribute:
1023
        return existingAttribute.value
5802 rajveer 1024
    return ""
5806 rajveer 1025
 
6019 rajveer 1026
def change_jacket_number(order_id, jacket_number):
1027
    order = get_order(order_id)
1028
    if order.status == OrderStatus.BILLED:
1029
        order.jacket_number = jacket_number
6047 rajveer 1030
        session.commit()
6019 rajveer 1031
        return True
1032
    return False
1033
 
1034
def mark_order_as_rto_in_transit(order_id):
1035
    order = get_order(order_id)
6032 rajveer 1036
    if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERY_SUCCESS]:
6019 rajveer 1037
        return False
1038
    order.status = OrderStatus.RTO_IN_TRANSIT
1039
    order.delivery_timestamp = datetime.datetime.now()
7151 amit.gupta 1040
    order.statusDescription = "Order Returned to Origin"
6019 rajveer 1041
    update_trust_level(order)
6032 rajveer 1042
    session.commit()
7767 amar.kumar 1043
    try:
1044
        alert_client = AlertClient().get_client()
1045
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1046
    except Exception as e:
1047
        print "Exception in ending alert in MarkOrderAsRTO method"
1048
        print e
6019 rajveer 1049
    return True
1050
 
483 rajveer 1051
def get_order(order_id):
1052
    order = Order.get_by(id=order_id)
1053
    if not order:
1054
        raise TransactionServiceException(108, "no such order")
1055
 
1056
    return order
1057
 
4999 phani.kuma 1058
def get_order_list(order_ids):
1059
    orders = Order.query.filter(Order.id.in_(tuple(order_ids)))
1060
    return orders
1061
 
5386 phani.kuma 1062
def get_order_list_for_vendor(order_ids, vendor_id):
1063
    if vendor_id == -1:
1064
        return get_order_list(order_ids)
1065
    else:
1066
        orders = Order.query.filter_by(vendorId = vendor_id).filter(Order.id.in_(tuple(order_ids)))
1067
        return orders
1068
 
3014 chandransh 1069
def get_orders_for_customer(customer_id, from_date, to_date, statuses):
483 rajveer 1070
    if not customer_id:
1071
        raise TransactionServiceException(101, "bad customer id")
1072
    query = Order.query.filter(Order.customer_id == customer_id)
3014 chandransh 1073
    if statuses:
1074
        query = query.filter(Order.status.in_(tuple(statuses)))
483 rajveer 1075
    if from_date:
1076
        query = query.filter(Order.created_timestamp >from_date)
1077
    if to_date:
1078
        query = query.filter(Order.created_timestamp < to_date)
1079
    return query.all()
1080
 
1528 ankur.sing 1081
def get_order_for_customer(order_id, customer_id):
1082
    if not customer_id:
1083
        raise TransactionServiceException(101, "bad customer id")
1084
    order = get_order(order_id)
1085
    if order.customer_id != customer_id:
1086
        raise TransactionServiceException(108, "order: " + str(order_id) + " does not belong to customer: " + str(customer_id))
1087
    return order
1088
 
4801 anupam.sin 1089
def get_all_orders(statuses, from_date, to_date, warehouse_id):
1090
    if not len(statuses):
1091
        raise TransactionServiceException(101, "Status list is empty")
1092
    query = Order.query.filter(Order.status.in_(statuses))
1093
    if warehouse_id:
1094
        query = query.filter(Order.warehouse_id == warehouse_id)
1095
        #raise TransactionServiceException(101, "bad warehouse id")
483 rajveer 1096
    if from_date:
1097
        query = query.filter(Order.created_timestamp >from_date)
1098
    if to_date:
1099
        query = query.filter(Order.created_timestamp < to_date)
1100
    return query.all()
1101
 
4133 chandransh 1102
def get_orders_in_batch(statuses=[], offset=0, limit=0, warehouse_id=None):
4296 rajveer 1103
    query = Order.query
1104
    if warehouse_id:
1105
        query = query.filter(Order.warehouse_id == warehouse_id)
4133 chandransh 1106
    if statuses:
1107
        query = query.filter(Order.status.in_(statuses))
1108
    query = query.offset(offset)
1109
    if limit:
1110
        query = query.limit(limit)
1111
    return query.all()
1112
 
1113
def get_order_count(statuses=[], warehouse_id=None):
1114
    if not warehouse_id:
1115
        raise TransactionServiceException(101, "bad warehouse id")
1116
    query = session.query(func.count(Order.id)).filter(Order.warehouse_id == warehouse_id)
1117
    if statuses:
1118
        query = query.filter(Order.status.in_(statuses))
1119
    return query.scalar()
1120
 
1382 varun.gupt 1121
def get_returnable_orders_for_customer(customer_id, limit = None):
1122
    if not customer_id:
1123
        raise TransactionServiceException(101, "bad customer id")
1124
 
1125
    query = Order.query.filter(Order.customer_id == customer_id)
1126
    query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)
1127
    query = query.filter(Order.status != OrderStatus.REJECTED)
1128
    query = query.filter(Order.status > OrderStatus.SHIPPED_FROM_WH)
1129
    query = query.filter(or_(Order.status < OrderStatus.DELIVERY_SUCCESS, Order.delivery_timestamp < datetime.datetime.now() + datetime.timedelta(hours = 48)))
1130
    orders = query.all()
1131
    order_ids = [order.id for order in orders]
1132
    return order_ids
1133
 
1134
def get_cancellable_orders_for_customer(customer_id, limit = None):
1135
    if not customer_id:
1136
        raise TransactionServiceException(101, "bad customer id")
4815 phani.kuma 1137
    cancellableOrderStatuses = OrderStatusGroups().codCancellable
1382 varun.gupt 1138
    query = Order.query.filter(Order.customer_id == customer_id)
4815 phani.kuma 1139
    query = query.filter(Order.status.in_(cancellableOrderStatuses))
1382 varun.gupt 1140
    orders = query.all()
1141
    return [order.id for order in orders]
1142
 
995 varun.gupt 1143
def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):
1144
    if not warehouse_id:
1145
        raise TransactionServiceException(101, "bad warehouse id")
1146
 
1147
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
1148
 
1149
    if status:
1150
        query = query.filter(Order.status == status)
1151
 
1152
    if start_billing_date:
1153
        query = query.filter(Order.billing_timestamp >= start_billing_date)
1154
 
1155
    if end_billing_date:
1156
        query = query.filter(Order.billing_timestamp <= end_billing_date)
1157
 
1158
    return query.all()
1159
 
3451 chandransh 1160
def get_orders_by_shipping_date(from_shipping_date, to_shipping_date, provider_id, warehouse_id, cod):
1161
    query = Order.query.filter(Order.cod == cod)
3427 chandransh 1162
 
1163
    if warehouse_id and warehouse_id != -1:
1164
        query = query.filter(Order.warehouse_id == warehouse_id)
1165
 
1166
    if provider_id and provider_id != -1:
1167
        query = query.filter(Order.logistics_provider_id == provider_id)
1168
 
1169
    if from_shipping_date:
1170
        query = query.filter(Order.shipping_timestamp >= from_shipping_date)
1171
 
1172
    if to_shipping_date:
1173
        query = query.filter(Order.shipping_timestamp <= to_shipping_date)
1174
 
1175
    query = query.order_by(Order.airwaybill_no)
1176
 
1177
    return query.all()
1178
 
1528 ankur.sing 1179
def get_orders_for_transaction(transaction_id, customer_id):
1180
    orders = Order.query.filter_by(transaction_id=transaction_id, customer_id=customer_id).all()
1181
 
1208 chandransh 1182
    if not orders:
1183
        raise TransactionServiceException(101, "No order for the transaction")
1184
    return orders
1185
 
1405 ankur.sing 1186
def get_undelivered_orders(provider_id, warehouse_id):
1187
    query = Order.query
1188
    if provider_id != -1:
1189
        query = query.filter_by(Order.logistics_provider_id == provider_id)
1190
    if warehouse_id != -1:
1191
        query = query.filter(Order.warehouse_id == warehouse_id)
1192
    query = query.filter(and_(Order.status != OrderStatus.DELIVERY_SUCCESS, Order.status != OrderStatus.FAILED, \
1193
                              Order.status > OrderStatus.SHIPPED_FROM_WH))
1479 ankur.sing 1194
    #Get last midnight time instead of current time as courier company would have sent the 
1195
    #delivery records updated at least till midnight and not by the current time.
1196
    time_format = "%Y-%m-%d %H:%M:%S.%f"
1197
    t = time.strptime(str(datetime.datetime.now()), time_format)
1198
    midnightTime = datetime.datetime(*t[:3])
1199
    query = query.filter(Order.expected_delivery_time < midnightTime)
1405 ankur.sing 1200
    orders = query.all()
1201
    return orders
1202
 
1208 chandransh 1203
def get_line_items_for_order(order_id):
1204
    query = LineItem.query.filter(LineItem.order_id == order_id)
1205
    return query.all()
1206
 
483 rajveer 1207
def change_order_status(self, orderId, status, description):
1208
    order = get_order(orderId)
1209
    order.status = status
1210
    order.statusDescription = description
1211
    session.commit()
3578 mandeep.dh 1212
    update_trust_level(order)
1213
    return True
3499 mandeep.dh 1214
 
3578 mandeep.dh 1215
def update_trust_level(order):
3530 mandeep.dh 1216
    try:
3578 mandeep.dh 1217
        trust_level_delta = 0
1218
        if order.cod == True:
1219
            trust_level_delta = ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT.get(order.status, 0)
1220
 
3530 mandeep.dh 1221
        if (trust_level_delta != 0):
1222
            user_client = UserClient().get_client()
1223
            user_client.increaseTrustLevel(order.customer_id, trust_level_delta)
1224
    except Exception as e:
1225
        print e
3499 mandeep.dh 1226
 
483 rajveer 1227
    return True
3064 chandransh 1228
 
7391 rajveer 1229
def verify_order(orderId):
3064 chandransh 1230
    logging.info("Verifying order no: " + str(orderId))
1231
    order = get_order(orderId)
4662 rajveer 1232
    if order.status == OrderStatus.COD_VERIFICATION_PENDING:
3064 chandransh 1233
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
1234
        order.statusDescription = "Submitted for processing"
1235
        order.verification_timestamp = datetime.datetime.now()
1236
        session.commit()
7423 anupam.sin 1237
 
7344 rajveer 1238
        if order.source == OrderSource.STORE:
7423 anupam.sin 1239
            sod = StoreOrderDetail.get_by(orderId = order.id)
1240
            __push_store_collection_to_hotspot(order, "advance", sod.cashAmount, sod.cardAmount)
3064 chandransh 1241
        logging.info("Successfully verified order no: " + str(orderId))
1242
        return True
1243
    else:
1244
        logging.warning("Verify called for order no." + str(orderId) +" which is not in verification pending state");
1245
        return False
1246
 
4285 rajveer 1247
def accept_order(orderId):
3064 chandransh 1248
    logging.info("Accepting order no: " + str(orderId))
921 rajveer 1249
    order = get_order(orderId)
5110 mandeep.dh 1250
    if order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.CAPTURE_IN_PROCESS]:
3064 chandransh 1251
        if not order.cod:
1252
            if order.transaction.status == TransactionStatus.AUTHORIZED:
4421 mandeep.dh 1253
                __capture_txn(order)
3010 chandransh 1254
        order.status = OrderStatus.ACCEPTED
1255
        order.statusDescription = "Order Accepted"
1256
        order.accepted_timestamp = datetime.datetime.now()
5530 mandeep.dh 1257
        __amend_fulfilment_warehouse(order)
6789 rajveer 1258
        __update_transfer_price(order, order.fulfilmentWarehouseId)
3010 chandransh 1259
        session.commit()
3064 chandransh 1260
        logging.info("Successfully accepted the order no.:" + str(orderId))
3010 chandransh 1261
        return True
1262
    else:
3064 chandransh 1263
        logging.warning("Accept called for the unacceptable order: " + str(orderId))
3010 chandransh 1264
        return False
921 rajveer 1265
 
4421 mandeep.dh 1266
def __capture_txn(order):
1267
    txnId = order.transaction_id
3010 chandransh 1268
    logging.info("Capturing payment for merchant txn:" + str(txnId))
4421 mandeep.dh 1269
    try:
1270
        payment_client = PaymentClient().get_client()
1271
        capture_result = payment_client.capturePayment(txnId)
1272
        if capture_result:
1273
            logging.info("Successfully captured payment for merchant txn:" + str(txnId))
7293 anupam.sin 1274
            change_transaction_status(txnId, TransactionStatus.IN_PROCESS, "Payment received", PickUpType.COURIER, order.orderType, order.source)
4421 mandeep.dh 1275
        else:
1276
            raise TransactionServiceException(115, "Payment capture failed.")
1277
    except PaymentException as e:
1278
        if e.error_code == 106:
1279
            order.status = OrderStatus.CAPTURE_IN_PROCESS
1280
            session.commit()
1281
            raise TransactionServiceException(122, "Unable to capture payment due to connection issue.")
1282
        else:
1283
            raise TransactionServiceException(115, "Payment capture failed.")
3010 chandransh 1284
 
5530 mandeep.dh 1285
def __amend_fulfilment_warehouse(order):
1286
    itemId = order.lineitems[0].item_id
5944 mandeep.dh 1287
    inventoryClient = InventoryClient().get_client()
1288
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5530 mandeep.dh 1289
    if not (inventory.availability.has_key(order.fulfilmentWarehouseId) and inventory.availability[order.fulfilmentWarehouseId]):
5944 mandeep.dh 1290
        for warehouse in inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 0, order.warehouse_id, 0):
5558 mandeep.dh 1291
            if inventory.availability.has_key(warehouse.id) and inventory.availability[warehouse.id] >= inventory.reserved[warehouse.id] + order.lineitems[0].quantity:
5966 rajveer 1292
                inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, order.lineitems[0].quantity)
1293
                inventoryClient.reserveItemInWarehouse(itemId, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
5637 mandeep.dh 1294
                order.fulfilmentWarehouseId = warehouse.id
5530 mandeep.dh 1295
                break
1296
 
7720 amar.kumar 1297
def __isFreebieOrderBillable(order):
1298
    parentOrderId = get_order_attribute_value(order.id, "parentOrderIdForFreebie")
1299
    parentOrder = Order.get_by(id = parentOrderId)
1300
    if parentOrder.cod and parentOrder.status!=12:
1301
        return False
1302
    else:
1303
        return True
1304
 
7190 amar.kumar 1305
def add_billing_details(orderId, invoice_number, serialNumbers, itemNumbers, freebieWarehouseId, billedBy, jacketNumber, billingType, fulfilmentWarehouseId, authorize):
4285 rajveer 1306
    if jacketNumber is None or jacketNumber <= 0:
2783 chandransh 1307
        raise TransactionServiceException(110, "Invalid jacket number")
1308
 
4285 rajveer 1309
    if billedBy is None or billedBy.strip() == "":
2783 chandransh 1310
        raise TransactionServiceException(110, "Invalid Biller")
1311
 
1149 chandransh 1312
    order = Order.get_by(id=orderId)
1313
    if not order:
2783 chandransh 1314
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
5110 mandeep.dh 1315
 
7190 amar.kumar 1316
    '''
1317
    First checking whether freebie can be billed or not otherwise wont proceed.
1318
    '''
7198 amar.kumar 1319
    if order.freebieItemId:
1320
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1321
            if freebieWarehouseId:
7190 amar.kumar 1322
                try:
7198 amar.kumar 1323
                    inventory_client = InventoryClient().get_client()
1324
                    warehouse = inventory_client.getWarehouse(freebieWarehouseId)
1325
 
7199 amar.kumar 1326
                    if warehouse.warehouseType!= WarehouseType.OURS or warehouse.inventoryType != InventoryType.GOOD:
7198 amar.kumar 1327
                        raise TransactionServiceException(110,'Billing of Freebie is only allowed from OURS_GOOD warehouses ')
1328
 
7190 amar.kumar 1329
                    warehouse_client = WarehouseClient().get_client()
1330
                    inventoryItem = warehouse_client.scanfreebie(orderId, order.freebieItemId, freebieWarehouseId, ScanType.SALE);
1331
 
1332
                    attr = Attribute()
1333
                    attr.orderId = orderId
1334
                    attr.name = "freebie_tp"
1335
                    attr.value = str(inventoryItem.unitPrice)
1336
 
1337
                    attr1 = Attribute()
1338
                    attr1.orderId = orderId
1339
                    attr1.name = "freebie_vendor"
1340
                    attr1.value = str(inventoryItem.supplierId)
5966 rajveer 1341
 
7190 amar.kumar 1342
                    attr2 = Attribute()
1343
                    attr2.orderId = orderId
1344
                    attr2.name = "freebie_nlc"
7672 rajveer 1345
                    attr2.value = str(inventoryItem.nlc)
7190 amar.kumar 1346
                except Exception as e:
1347
                    print sys.exc_info()[0]
1348
                    print e.message
7198 amar.kumar 1349
                    raise TransactionServiceException(110,'Error in billing freebie for warehouseId ' + str(freebieWarehouseId))
1350
            else:
1351
                raise TransactionServiceException(110,'No warehouseId provided for billing of freebie ')
1352
        else:
1353
            raise TransactionServiceException(110,'Order with freebies associated with it cant be billed from an external warehouse ')
5110 mandeep.dh 1354
    lineitem = order.lineitems[0]
1355
    item_id = lineitem.item_id
7720 amar.kumar 1356
 
1357
    '''
1358
    Checking if order is a freebie split-order and if the order is cod and if the original order is marked as delivered.
1359
    '''
1360
    freebie_order_info_text = "Freebie Order for Order ID"
7723 amar.kumar 1361
    if lineitem.extra_info and freebie_order_info_text in lineitem.extra_info:
7720 amar.kumar 1362
        canbillOrder = __isFreebieOrderBillable(order)
1363
        if canbillOrder == False:
1364
            raise TransactionServiceException(110,'Parent order for this is COD and is still undelivered')
6007 rajveer 1365
#    inventoryClient = InventoryClient().get_client()
1366
#    if not inventoryClient.isOrderBillable(item_id, order.fulfilmentWarehouseId, sourceId, orderId):
1367
#        raise TransactionServiceException(101, "There are other orders to be billed before this order id " + str(orderId))
5966 rajveer 1368
 
5110 mandeep.dh 1369
    catalog_client = CatalogClient().get_client()
1370
    item = catalog_client.getItem(item_id)
4283 anupam.sin 1371
    if order.status == OrderStatus.ACCEPTED:
4285 rajveer 1372
        order.jacket_number = jacketNumber
6751 amar.kumar 1373
 
1374
        if itemNumbers:
1375
            lineitem.item_number = itemNumbers[0]    
7180 rajveer 1376
        if serialNumbers:
1377
            lineitem.serial_number = serialNumbers[0]                
1378
 
6787 rajveer 1379
        '''
6751 amar.kumar 1380
        if billingType == BillingType.EXTERNAL or billingType == BillingType.OURS_EXTERNAL:
4763 rajveer 1381
            if billedOrdersColorMap.has_key(orderId):
1382
                etpColor = billedOrdersColorMap.get(orderId)
1383
                ourColor = order.lineitems[0].color
4781 rajveer 1384
                if ourColor and etpColor != ourColor and not authorize:
4763 rajveer 1385
                    raise TransactionServiceException(777, "ETP color: " + etpColor + " and Order color: " + ourColor)
1386
                else:
1387
                    billedOrdersColorMap.pop(orderId)
6787 rajveer 1388
        '''
6751 amar.kumar 1389
 
1390
        if billingType == BillingType.EXTERNAL:            
1391
            order.invoice_number = invoice_number
1392
 
1393
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
6757 rajveer 1394
            if ItemType.SERIALIZED == item.type and not (serialNumbers and serialNumbers[0]):
1395
                raise TransactionServiceException(110, "No Serial Number supplied")
1396
            if serialNumbers:
1397
                lineitem.serial_number = serialNumbers[0]
6969 amar.kumar 1398
 
4283 anupam.sin 1399
 
2842 chandransh 1400
        order.status = OrderStatus.BILLED
1401
        order.statusDescription = "Order Billed"
1402
        order.billing_timestamp = datetime.datetime.now()
4285 rajveer 1403
        order.billed_by = billedBy
4435 mandeep.dh 1404
 
5436 mandeep.dh 1405
        # Letting the billing process fail in cases where we are unable to 
4435 mandeep.dh 1406
        # fill in transfer price
1407
        try:
5944 mandeep.dh 1408
            inventory_client = InventoryClient().get_client()
1409
            warehouse = inventory_client.getWarehouse(fulfilmentWarehouseId)
1410
            item_pricing = inventory_client.getItemPricing(item_id, warehouse.vendor.id)
5110 mandeep.dh 1411
            lineitem.transfer_price = item_pricing.transferPrice
6751 amar.kumar 1412
            lineitem.nlc = item_pricing.nlc
7330 amit.gupta 1413
            lineitem.vatRate = catalog_client.getVatPercentageForItem(lineitem.item_id, warehouse.stateId, lineitem.unit_price)
5110 mandeep.dh 1414
            order.vendorId = warehouse.vendor.id
4435 mandeep.dh 1415
        except InventoryServiceException as e:
1416
            print sys.exc_info()[0]
1417
            print e.message
5110 mandeep.dh 1418
            raise TransactionServiceException(110, 'Transfer price missing for itemId: ' + str(item_id) + ' and vendor: ' + str(warehouse.vendor.id))
4435 mandeep.dh 1419
 
5110 mandeep.dh 1420
        # For OUR warehouse, we need to scan out items for every billed order
1421
        if billingType == BillingType.OURS:
5530 mandeep.dh 1422
            for index, serialNumber in enumerate(serialNumbers):
5411 rajveer 1423
                try:
1424
                    warehouse_client = WarehouseClient().get_client()
5436 mandeep.dh 1425
                    # Fetching GOOD w/h corresponding to the virtual one here
5835 mandeep.dh 1426
                    if not warehouse.billingWarehouseId:
5950 mandeep.dh 1427
                        warehouse = inventory_client.getWarehouses(None, InventoryType.GOOD, warehouse.vendor.id, order.warehouse_id, 0)[0]
5436 mandeep.dh 1428
 
5411 rajveer 1429
                    if ItemType.SERIALIZED == item.type:
1430
                        inventoryItem = warehouse_client.getInventoryItem(serialNumber)
1431
                    else:
5661 mandeep.dh 1432
                        inventoryItem = warehouse_client.getNonSeralizedInventoryItem(itemNumbers[index], item_id, warehouse.id)
5411 rajveer 1433
 
1434
                    if (inventoryItem.itemId != item_id):
1435
                        catalog_client = CatalogClient().get_client()
1436
                        item = catalog_client.getItem(inventoryItem.itemId)
1437
                        scanItemString = " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
1438
                        lineItemString = " ".join([str(lineitem.brand), str(lineitem.model_name), str(lineitem.model_number), str(lineitem.color)])
1439
                        raise TransactionServiceException(110, 'Trying to scan ' + scanItemString + ' instead of ' + lineItemString)
1440
 
1441
                    if ItemType.SERIALIZED == item.type:
5661 mandeep.dh 1442
                        inventoryItem = warehouse_client.scanSerializedItemForOrder(serialNumber, ScanType.SALE, orderId, warehouse.id, 1, order.warehouse_id)
5411 rajveer 1443
                    else:
5661 mandeep.dh 1444
                        inventoryItem = warehouse_client.scanForOrder(inventoryItem, ScanType.SALE, 1, order.id, warehouse.id, order.warehouse_id)
5411 rajveer 1445
 
1446
                    lineitem.transfer_price = inventoryItem.unitPrice
7672 rajveer 1447
                    lineitem.nlc = inventoryItem.nlc
5411 rajveer 1448
                    order.vendorId = inventoryItem.supplierId
5636 amar.kumar 1449
                    catalog_client = CatalogClient().get_client()
5411 rajveer 1450
                except WarehouseServiceException as e:
1451
                    print sys.exc_info()[0]
1452
                    print 'Could not scan out orders due to: ' + e.message
1453
                    raise TransactionServiceException(110, e.message)
6763 amar.kumar 1454
        elif billingType == BillingType.OURS_EXTERNAL:
1455
            try:
6786 amar.kumar 1456
                if ItemType.SERIALIZED == item.type:
1457
                    serialNumber = serialNumbers[0]
1458
                else:
1459
                    serialNumber = ""
6763 amar.kumar 1460
                warehouse_client = WarehouseClient().get_client()
7672 rajveer 1461
                inventoryItem = warehouse_client.scanForOursExternalSale(lineitem.item_id, serialNumber, lineitem.item_number, invoice_number, order.fulfilmentWarehouseId, lineitem.transfer_price, lineitem.nlc, order.id)
6763 amar.kumar 1462
                lineitem.transfer_price = inventoryItem.unitPrice
7672 rajveer 1463
                lineitem.nlc = inventoryItem.nlc
6763 amar.kumar 1464
                order.vendorId = inventoryItem.supplierId
1465
            except WarehouseServiceException as e:
1466
                print sys.exc_info()[0]
1467
                print 'Could not scan out orders due to: ' + e.message
1468
                raise TransactionServiceException(110, e.message)
5123 mandeep.dh 1469
        else:
1470
            if not warehouse.isAvailabilityMonitored:
5944 mandeep.dh 1471
                inventory_client = InventoryClient().get_client()
1472
                inventory_client.addInventory(item.id, warehouse.id, -1 * lineitem.quantity)
4365 mandeep.dh 1473
 
5110 mandeep.dh 1474
        __update_inventory_reservation(order)
5661 mandeep.dh 1475
        order.fulfilmentWarehouseId = warehouse.id
6969 amar.kumar 1476
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1477
            order.invoice_number = get_next_invoice_number(order.orderType)
4541 mandeep.dh 1478
        session.commit()
4283 anupam.sin 1479
        return True
1480
    else:
1481
        return False
1149 chandransh 1482
 
6751 amar.kumar 1483
def add_invoice_number(orderId, invoiceNumber, color, serialNumber, itemNumber):
4579 rajveer 1484
    order = Order.get_by(id=orderId)
1485
    if not order:
1486
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
1487
 
1488
    if order.status == OrderStatus.ACCEPTED:
1489
        order.invoice_number = invoiceNumber
4767 rajveer 1490
        if color:
6764 rajveer 1491
            billedOrdersColorMap[orderId] = color
6751 amar.kumar 1492
        if serialNumber:
6764 rajveer 1493
            order.lineitems[0].serial_number = serialNumber.strip() 
6751 amar.kumar 1494
        if itemNumber:
6764 rajveer 1495
            order.lineitems[0].item_number = itemNumber.strip()
4579 rajveer 1496
    session.commit()
1497
 
1220 chandransh 1498
def batch_orders(warehouseId):
1499
    if not warehouseId:
1500
        raise TransactionServiceException(101, "bad warehouse id")
1225 chandransh 1501
 
1502
    batchno_generator = BatchNoGenerator()
1503
    session.commit()
1220 chandransh 1504
    query = Order.query.filter_by(warehouse_id=warehouseId)
4592 mandeep.dh 1505
    query = query.filter(Order.status == OrderStatus.LOW_INV_PO_RAISED)
1220 chandransh 1506
    query = query.order_by(Order.created_timestamp)
1507
    pending_orders = query.all()
1225 chandransh 1508
 
1220 chandransh 1509
    serial_no = 1
1510
    for order in pending_orders:
1276 chandransh 1511
        order.batchNo = batchno_generator.id
1220 chandransh 1512
        order.serialNo = serial_no
1513
        serial_no += 1
1514
    session.commit() 
1515
    pending_orders = query.all()
1516
    return pending_orders
1517
 
1518
def order_outofstock(orderId):
1911 chandransh 1519
    '''
1520
    Mark order as out of stock
1521
    '''
1220 chandransh 1522
    order = get_order(orderId)
1523
    order.status = OrderStatus.INVENTORY_LOW
1524
    order.statusDescription = "Low Inventory"
1525
    order.outofstock_timestamp = datetime.datetime.now()
1526
    session.commit()
1527
    return True
1528
 
4789 rajveer 1529
def mark_orders_as_shipped_from_warehouse(warehouseId, providerId, cod, orderIds):
4410 rajveer 1530
    try:
1531
        current_timestamp = datetime.datetime.now()
5822 rajveer 1532
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(warehouse_id = warehouseId, logistics_provider_id = providerId, status = OrderStatus.BILLED).all()
4410 rajveer 1533
        for order in orders:
5822 rajveer 1534
            order.status = OrderStatus.SHIPPED_FROM_WH
1535
            order.statusDescription = "Order shipped from warehouse"
1536
            order.shipping_timestamp = current_timestamp
1537
            try:
1538
                print "Trying to schedule alert"
1539
                monitoredEntity = MonitoredEntity();
1540
                monitoredEntity.entityType=EntityType.COURIER;
1541
                monitoredEntity.eventType=OrderStatus.SHIPPED_FROM_WH;
1542
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1543
                adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1544
                sec = datetime.datetime.now()
1545
                #Warn alert time is taken as 16 hrs
1546
                warn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=16))
1547
                #Critical alert time is taken as 26 hrs                    
1548
                critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=26))
1549
                monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1550
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1551
                monitoredEntity.description="warehouseId = " + str(warehouseId) + " providerId = " + str(providerId) + " orderId = "  + str(order.id);
1552
                alert_client = AlertClient().get_client()
1553
                alert_client.scheduleAlert(monitoredEntity)
1554
            except Exception as e:
1555
                print "Exception in scheduling alert in ShippedFromWarehouse method"
1556
                print e
759 chandransh 1557
        session.commit()
5832 rajveer 1558
 
4749 varun.gupt 1559
 
1560
        try:
5832 rajveer 1561
            for order in orders:
1562
                if order.pickupStoreId:
1563
                    send_mails_to_bdms(order)
1564
                else:
1565
                    enqueue_shipping_confirmation_email(order)
4749 varun.gupt 1566
        except Exception as e:
1567
            print e
5832 rajveer 1568
 
759 chandransh 1569
        return True
1570
    except:
1571
        return False
4410 rajveer 1572
 
5832 rajveer 1573
def send_mails_to_bdms(order):
5816 rajveer 1574
    logistics_client = LogisticsClient().get_client()
5832 rajveer 1575
    store = logistics_client.getPickupStore(order.pickupStoreId)
1576
    provider = logistics_client.getProvider(order.logistics_provider_id)
6029 rajveer 1577
    subject = source_name + " order " + str(order.id) +" shipped to store" 
5832 rajveer 1578
    raw_message = '''
1579
    Dear Sir,
5816 rajveer 1580
 
5832 rajveer 1581
    Order mentioned below is being shipped to your store. Customer will pick it from your store. 
1582
 
1583
    Store Id: %(store_id)s
1584
    Order Id: %(order_id)s 
1585
    Product: %(product)s
1586
    Delivery By: %(provider)s
5844 mandeep.dh 1587
    Payment Mode: %(payMode)s
1588
 
1589
    %(note)s
1590
 
5832 rajveer 1591
    Thanks and Regards
1592
    Sandeep Sachdeva
1593
    '''
1594
 
5844 mandeep.dh 1595
    payMode = 'Prepaid'
1596
    note = ''
1597
    if order.cod:
1598
        payMode = 'COD'
6318 rajveer 1599
        note = 'Note: Please collect Rs. ' + str(order.total_amount-order.gvAmount) + ' from customer'
5844 mandeep.dh 1600
 
5832 rajveer 1601
    message = dedent(raw_message) % { 'order_id' : str(order.id),
1602
                                     'store_id' : str(store.hotspotId),
1603
                                  'provider' : provider.name,
5844 mandeep.dh 1604
                                  'product' : str(order.lineitems[0]),
1605
                                  'payMode' : payMode,
1606
                                  'note'    : note
5832 rajveer 1607
                                  }
6643 rajveer 1608
    to_addresses = [store.email, store.bdmEmail, 'sandeep.sachdeva@shop2020.in', 'amit.sirohi@shop2020.in', 'manoj.kumar@shop2020.in']
5894 rajveer 1609
    cc = ['khushal.bhatia@spiceretail.co.in']
1610
    bcc = ['rajneesh.arora@spiceretail.co.in']
5966 rajveer 1611
    mail(mail_user, mail_password, to_addresses, subject, message, [], cc, bcc)
5816 rajveer 1612
 
5713 rajveer 1613
def mark_orders_as_returned_from_store(providerId, orderIds, awbs):
5676 rajveer 1614
    try:
1615
        current_timestamp = datetime.datetime.now()
5824 rajveer 1616
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(logistics_provider_id = providerId, status = OrderStatus.RET_PICKUP_REQUEST_RAISED).all()
5676 rajveer 1617
        for order in orders:
6943 amar.kumar 1618
            order.status = OrderStatus.RTO_IN_TRANSIT
5824 rajveer 1619
            order.statusDescription = "Order returned from store"
1620
            order.doa_pickup_timestamp = current_timestamp
1621
            #order.airwaybill_no = awbs[orderIds.index(order.id)]
1622
            order.tracking_id = awbs[orderIds.index(order.id)]
5676 rajveer 1623
        session.commit()
1624
 
1625
        return True
1626
    except:
1627
        return False    
1628
 
1629
def set_order_attributes(orderId, attributes):
5871 rajveer 1630
    for attribute in attributes :
1631
        existingAttribute = Attribute.query.filter(Attribute.orderId == orderId).filter(Attribute.name == attribute.name).first()
1632
        if existingAttribute:
1633
            existingAttribute.value = attribute.value
1634
        else :                
1635
            attr = Attribute()
1636
            attr.orderId = orderId
1637
            attr.name = attribute.name
1638
            attr.value = attribute.value
5791 anupam.sin 1639
    session.commit()
5724 rajveer 1640
 
1113 chandransh 1641
def mark_orders_as_picked_up(provider_id, pickup_details):
1642
    for awb, pickup_timestamp in pickup_details.iteritems():
1135 chandransh 1643
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
2684 chandransh 1644
        if order == None or order.status != OrderStatus.SHIPPED_FROM_WH:
2220 chandransh 1645
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1646
            continue
1113 chandransh 1647
        order.status = OrderStatus.SHIPPED_TO_LOGST
1648
        order.statusDescription = "Order picked up by Courier Company"
1246 chandransh 1649
        order.pickup_timestamp = pickup_timestamp
5636 amar.kumar 1650
 
1651
        try:
1652
            monitoredEntity = MonitoredEntity();
1653
            monitoredEntity.entityType=EntityType.COURIER;
1654
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_LOGST
1655
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
7822 amar.kumar 1656
            adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 2);
5744 amar.kumar 1657
            sec = datetime.datetime.now()
7822 amar.kumar 1658
            #Warn alert time is taken as 26 hrs
1659
            warn_time = (sec + timedelta(days=(adjustedDeliveryDays-2)) + timedelta(hours=26))
1660
            #Critical alert time is taken as 36 hrs                    
1661
            critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=36))
5744 amar.kumar 1662
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1663
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5819 amit.gupta 1664
            monitoredEntity.description="providerId = " + str(provider_id)
5636 amar.kumar 1665
            alert_client = AlertClient().get_client()
1666
            alert_client.updateMonitoredObject(monitoredEntity)
1667
        except Exception as e:
5801 amar.kumar 1668
            print "Exception in updating alert in MarkOrdersAsPickedUp method"
5636 amar.kumar 1669
            print e
1113 chandransh 1670
    session.commit()
1217 chandransh 1671
 
4910 phani.kuma 1672
def get_orders_not_picked_up(provider_id):
1132 chandransh 1673
    current_time = datetime.datetime.now()
1674
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4741 phani.kuma 1675
    orders_not_picked_up = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.SHIPPED_FROM_WH).filter(Order.shipping_timestamp <= to_datetime).all()
1113 chandransh 1676
    return orders_not_picked_up
1677
 
1132 chandransh 1678
def mark_orders_as_delivered(provider_id, delivered_orders):
1679
    for awb, detail in delivered_orders.iteritems():
1135 chandransh 1680
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4910 phani.kuma 1681
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
1911 chandransh 1682
            continue
6561 amit.gupta 1683
        timestamp, receiver = detail.split('|')
1684
        order.delivery_timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
1685
        if order.first_dlvyatmp_timestamp is None:
1686
            order.first_dlvyatmp_timestamp = order.delivery_timestamp
1687
        order.receiver = receiver
5555 rajveer 1688
        if order.pickupStoreId:
1689
            order.status = OrderStatus.DELIVERED_AT_STORE
1690
            order.statusDescription = "Order delivered At Store"
5762 amar.kumar 1691
            try:
1692
                monitoredEntity = MonitoredEntity();
1693
                monitoredEntity.entityType=EntityType.COURIER;
7832 amar.kumar 1694
                monitoredEntity.eventType=OrderStatus.DELIVERED_AT_STORE;
5762 amar.kumar 1695
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1696
                #adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1697
                sec = datetime.datetime.now()
1698
                #Critical alert time is taken as 26 hrs                    
1699
                critical_time = (sec + timedelta(hours=4))
1700
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1701
                monitoredEntity.description="deliveryTimeAtStore = " + str(order.delivery_timestamp) + " orderId = "  + str(order.id);
1702
                alert_client = AlertClient().get_client()
1703
                alert_client.updateMonitoredObject(monitoredEntity)
1704
            except Exception as e:
1705
                print e
5555 rajveer 1706
        else:
1707
            order.status = OrderStatus.DELIVERY_SUCCESS
1708
            order.statusDescription = "Order delivered"
5762 amar.kumar 1709
            update_trust_level(order)
6903 anupam.sin 1710
            if order.insuranceDetails:
6906 rajveer 1711
                try:
1712
                    update_insurance_details(order)
1713
                except:
1714
                    print "Error generating insurance file for order " + str(order.id)
1715
                    session.rollback()
1716
                    return
1717
 
6745 anupam.sin 1718
            if enqueue_delivery_success_mail(order) :
1719
                session.commit()
1720
            else :
1721
                session.rollback()
5762 amar.kumar 1722
            try:
1723
                alert_client = AlertClient().get_client()
1724
                alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1725
            except Exception as e:
5801 amar.kumar 1726
                print "Exception in scheduling alert in ShippedFromWarehouse method"
5762 amar.kumar 1727
                print e
5636 amar.kumar 1728
 
6906 rajveer 1729
def update_insurance_details(order):
1730
    order.insuranceDetails[0].startDate = order.delivery_timestamp
1731
    order.insuranceDetails[0].expiryDate = order.delivery_timestamp + timedelta(days = 365)
6947 rajveer 1732
    filename = "/tmp/" + str(order.id) + "-insurance-policy.pdf"
6906 rajveer 1733
    __generate_policy_doc(order, filename)
1734
    file = open(filename, "rb")
1735
    pdfFile = file.read()
1736
    doc = DocumentStore()
1737
    doc.docType = 1
1738
    doc.docSource = order.id
1739
    doc.document = pdfFile
1132 chandransh 1740
 
4712 rajveer 1741
def mark_order_as_delivered(orderId, deliveryTimestamp, receiver):
1742
    order = Order.get_by(id=orderId)
5555 rajveer 1743
    if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_RECEIVED, OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_AUTHORIZED, OrderStatus.RET_PICKUP_REQUEST_RAISED, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:
7746 amit.gupta 1744
        raise TransactionServiceException(101, "Either wrong order id or invalid state " + str(orderId))
5402 rajveer 1745
 
1746
    # Provider is 4 is for self pickup and hardcoded. We should figure out a way to not to hard code.   
1747
    if order.status == OrderStatus.BILLED and order.logistics_provider_id != 4:
5807 rajveer 1748
        raise TransactionServiceException(101, "Order is not marked for self pickup: " + str(orderId))
5402 rajveer 1749
 
5555 rajveer 1750
    if order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:
6632 amit.gupta 1751
        order.delivery_timestamp = deliveryTimestamp
6631 amit.gupta 1752
        if order.first_dlvyatmp_timestamp is None:
6632 amit.gupta 1753
            order.first_dlvyatmp_timestamp = deliveryTimestamp
4712 rajveer 1754
        order.receiver = receiver
1755
    order.status = OrderStatus.DELIVERY_SUCCESS
1756
    order.statusDescription = "Order delivered"
1757
    update_trust_level(order)
6903 anupam.sin 1758
    if order.insuranceDetails:
6906 rajveer 1759
        try:
1760
            update_insurance_details(order)
1761
        except:
1762
            print "Error generating insurance file for order " + str(order.id)
1763
            session.rollback()
1764
            return
7409 anupam.sin 1765
 
1766
    if order.source == 2:
1767
        sod = StoreOrderDetail.get_by(orderId = order.id)
1768
        sod.payStatus = StorePaymentStatus.FULL_PAY_RECEIVED
4712 rajveer 1769
    session.commit()
5713 rajveer 1770
 
5812 rajveer 1771
    if order.pickupStoreId and order.cod:
5806 rajveer 1772
        __push_collection_to_hotspot(order, "SALE")
1773
 
5966 rajveer 1774
    enqueue_delivery_success_mail(order)
5713 rajveer 1775
#    if order.pickupStoreId:
1776
#        payment_client = PaymentClient().get_client()
1777
#        payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
1778
#        payment_client = PaymentClient().get_client()
1779
#        payment_client.partiallyCapturePayment(order.transaction.id, order.total_amount, xferBy, xferTxnId, now())
1780
#        order.cod_reconciliation_timestamp = datetime.datetime.now()
1781
#        session.commit()
1782
 
5636 amar.kumar 1783
    try:
1784
        alert_client = AlertClient().get_client()
5744 amar.kumar 1785
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1786
    except Exception as e:
5801 amar.kumar 1787
        print "Exception in ending alert in MarkOrderAsDelivered method"
5636 amar.kumar 1788
        print e
1789
 
4712 rajveer 1790
 
5555 rajveer 1791
def mark_order_as_received_at_store(orderId, deliveryTimestamp):
1792
    order = Order.get_by(id=orderId)
1793
    if order != None or order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE]:
1794
        order.status = OrderStatus.RECEIVED_AT_STORE
1795
        order.statusDescription = "Order received at store"
1796
        order.delivery_timestamp = deliveryTimestamp
1797
    session.commit()
5713 rajveer 1798
    try:
5762 amar.kumar 1799
        alert_client = AlertClient().get_client()
1800
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1801
    except Exception as e:
1802
        print e
1803
 
1804
    try:
5713 rajveer 1805
        enqueue_received_at_store_email(order)
1806
    except Exception as e:
1807
        print e
1808
 
1809
 
5555 rajveer 1810
 
4910 phani.kuma 1811
def mark_orders_as_rto(provider_id, returned_orders):
1135 chandransh 1812
    for awb, detail in returned_orders.iteritems():
1813
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
5713 rajveer 1814
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
2684 chandransh 1815
            continue
1816
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
4484 rajveer 1817
        order.status = OrderStatus.RTO_IN_TRANSIT
1135 chandransh 1818
        order.delivery_timestamp, reason = detail.split('|')
1819
        order.statusDescription = "Order Returned to Origin:" + reason
3578 mandeep.dh 1820
        update_trust_level(order)
1911 chandransh 1821
    session.commit()
5636 amar.kumar 1822
    try:
1823
        alert_client = AlertClient().get_client()
5801 amar.kumar 1824
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1825
    except Exception as e:
5801 amar.kumar 1826
        print "Exception in ending alert in MarkOrderAsRTO method"
5636 amar.kumar 1827
        print e
1135 chandransh 1828
 
4910 phani.kuma 1829
def get_rto_orders(provider_id):
1830
    current_time = datetime.datetime.now()
1831
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1832
    rto_orders = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.RTO_IN_TRANSIT).filter(Order.delivery_timestamp <= to_datetime).all()
1833
    return rto_orders
1834
 
5555 rajveer 1835
def get_receive_pending_orders(storeId):
1836
    return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE))).all()
1837
 
1838
def get_received_at_store_orders(storeId):
5676 rajveer 1839
    return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.RECEIVED_AT_STORE, OrderStatus.RET_PICKUP_REQUEST_RAISED))).all()
5555 rajveer 1840
 
5713 rajveer 1841
def get_orders_collection_at_store(storeId, fromDate, toDate, onlyCod):
1842
    query = Order.query.filter(Order.status == OrderStatus.DELIVERY_SUCCESS)
1843
    if storeId:
1844
        query = query.filter_by(pickupStoreId = storeId)
5720 rajveer 1845
    else:
1846
        query = query.filter(Order.pickupStoreId != 0)
5713 rajveer 1847
    if onlyCod:
1848
        query = query.filter_by(cod = onlyCod)
1849
    if fromDate:
1850
        query = query.filter(Order.delivery_timestamp >= fromDate)
1851
    if toDate:
1852
        query = query.filter(Order.delivery_timestamp <= toDate)
1853
    return query.all()
1854
 
1246 chandransh 1855
def update_non_delivery_reason(provider_id, undelivered_orders):
1856
    for awb, reason in undelivered_orders.iteritems():
1857
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4920 phani.kuma 1858
        if order == None or order.status == OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE:
2684 chandransh 1859
            continue
1860
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1246 chandransh 1861
        order.statusDescription = reason
1862
    session.commit()
4910 phani.kuma 1863
 
1864
def get_non_delivered_orders_by_courier(provider_id):
4581 phani.kuma 1865
    current_time = datetime.datetime.now()
1866
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1867
    upto_datetime = today_datetime - datetime.timedelta(4)
4910 phani.kuma 1868
    orders_not_delivered = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE))).filter(or_(Order.shipping_timestamp <= upto_datetime, Order.pickup_timestamp <= upto_datetime)).all()
4581 phani.kuma 1869
    return orders_not_delivered
1246 chandransh 1870
 
4910 phani.kuma 1871
def mark_orders_as_local_connected(provider_id, local_connected_orders):
1872
    for awb, timestamp in local_connected_orders.iteritems():
1873
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1874
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST]:
1875
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1876
            continue
1877
        order.status = OrderStatus.SHIPPED_TO_DESTINATION_CITY
1878
        order.statusDescription = "Left Out of Origin City"
5636 amar.kumar 1879
        current_time = datetime.datetime.now()
1880
        order.local_connected_timestamp = datetime.datetime(current_time.year, current_time.month, current_time.day)
1881
        try:
1882
            monitoredEntity = MonitoredEntity();
1883
            monitoredEntity.entityType=EntityType.COURIER;
1884
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_DESTINATION_CITY
1885
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
7822 amar.kumar 1886
 
1887
            sec = datetime.datetime.now()
1888
            #Warn alert time is taken as 14 hrs less than expected delivery time
1889
            warn_time1 = (order.expected_delivery_time-timedelta(hours = 14))
1890
            warn_time2 = sec + timedelta(order.expected_delivery_time - order.expected_shipping_timestamp) - timedelta(sec - order.shipping_time)
1891
            warn_time = max(warn_time1, warn_time2)
1892
 
5744 amar.kumar 1893
            #Critical alert time is taken as 13 hrs less than promised delivery time                    
7822 amar.kumar 1894
            critical_time1 = (order.expected_delivery_time-timedelta(hours = 10))
1895
            critical_time2  = sec + timedelta(order.expected_delivery_time - order.expected_shipping_timestamp) - timedelta(sec - order.shipping_time) + timedelta(hours = 5)
1896
            critical_time = max(critical_time1, critical_time2)
1897
 
5801 amar.kumar 1898
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1899
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1900
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1901
            alert_client = AlertClient().get_client()
1902
            alert_client.updateMonitoredObject(monitoredEntity)
1903
        except Exception as e:
5801 amar.kumar 1904
            print "Exception in updating alert in MarkOrderAsLocalConnected method"
5636 amar.kumar 1905
            print e
1906
        session.commit()
4910 phani.kuma 1907
 
1908
def get_orders_not_local_connected(provider_id):
1909
    current_time = datetime.datetime.now()
1910
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1911
    orders_pending_local_connection = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST))).filter(or_(Order.shipping_timestamp <= to_datetime, Order.pickup_timestamp <= to_datetime)).all()
1912
    return orders_pending_local_connection
1913
 
1914
def mark_orders_as_destinationCityReached(provider_id, destination_city_reached_orders):
1915
    for awb, timestamp in destination_city_reached_orders.iteritems():
1916
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1917
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY]:
1918
            continue
1919
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1920
        order.status = OrderStatus.REACHED_DESTINATION_CITY
1921
        order.statusDescription = "Reached Destination City"
1922
        order.reached_destination_timestamp = timestamp
5636 amar.kumar 1923
        try:
1924
            monitoredEntity = MonitoredEntity();
1925
            monitoredEntity.entityType=EntityType.COURIER;
1926
            monitoredEntity.eventType=OrderStatus.REACHED_DESTINATION_CITY
1927
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
7822 amar.kumar 1928
 
1929
            sec = datetime.datetime.now()
1930
            #Warn alert time is taken as expected delivery time
1931
            warn_time1 = (order.expected_delivery_time)
1932
            warn_time2 = sec + timedelta(order.expected_delivery_time - order.expected_shipping_timestamp) - timedelta(sec - order.shipping_time)
1933
            warn_time = max(warn_time1, warn_time2)
1934
 
1935
            #Critical alert time is taken as 13 hrs less than promised delivery time                    
1936
            critical_time1 = (order.expected_delivery_time + timedelta(hours = 5))
1937
            critical_time2  = sec + timedelta(order.expected_delivery_time - order.expected_shipping_timestamp) - timedelta(sec - order.shipping_time) + timedelta(hours = 5)
1938
            critical_time = max(critical_time1, critical_time2)
1939
 
5801 amar.kumar 1940
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1941
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1942
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1943
            alert_client = AlertClient().get_client()
1944
            alert_client.updateMonitoredObject(monitoredEntity)
1945
        except Exception as e:
5801 amar.kumar 1946
            print "Exception in updating alert in MarkOrderAsDestCityReached method"
5636 amar.kumar 1947
            print e
4910 phani.kuma 1948
    session.commit()
1949
 
1950
def mark_orders_as_firstDeliveryAttempted(provider_id, first_atdl_orders):
1951
    for awb, detail in first_atdl_orders.iteritems():
1952
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1953
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY]:
1954
            continue
1955
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1956
        order.status = OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1957
        order.first_dlvyatmp_timestamp, reason = detail.split('|')
1958
        order.statusDescription = reason
5636 amar.kumar 1959
        try:
1960
            monitoredEntity = MonitoredEntity();
1961
            monitoredEntity.entityType=EntityType.COURIER;
1962
            monitoredEntity.eventType=OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1963
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1964
            adjustedDeliveryDaysfor1day = adjust_delivery_time(datetime.datetime.now(), 1);
1965
            adjustedDeliveryDaysfor2days = adjust_delivery_time(datetime.datetime.now(), 2);
1966
            sec = datetime.datetime.now()
1967
            #Warn alert time is taken as 16 hrs
1968
            warn_time = (sec + timedelta(days=(adjustedDeliveryDaysfor1day-1)) + timedelta(hours=24))
1969
            #Critical alert time is taken as 26 hrs                    
7829 amar.kumar 1970
            critical_time = (sec + timedelta(days=(adjustedDeliveryDaysfor2days-2)) + timedelta(hours=48))
5744 amar.kumar 1971
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1972
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1973
            monitoredEntity.description="providerId = " + str(provider_id) + " first attempt timestamp" + order.first_dlvyatmp_timestamp
1974
            alert_client = AlertClient().get_client()
1975
            alert_client.updateMonitoredObject(monitoredEntity)
1976
        except Exception as e:
5801 amar.kumar 1977
            print "Exception in updating alert in MarkOrdersAsFirstDeliveryAttempted method"
5636 amar.kumar 1978
            print e
4910 phani.kuma 1979
    session.commit()
1980
 
4783 phani.kuma 1981
def get_orders_not_met_expected_delivery_date():
1982
    current_time = datetime.datetime.now()
1983
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4910 phani.kuma 1984
    orders_not_delivered = Order.query.filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY))).filter(Order.expected_delivery_time <= today_datetime).all()
4783 phani.kuma 1985
    return orders_not_delivered
1986
 
4444 rajveer 1987
def get_alerts(type, warehouseId, status, timestamp):
1988
    query = Alert.query.filter(Alert.warehouseId == warehouseId)
1989
    if type != -1 :
1990
        query = query.filter(Alert.type == type)
1991
    if status != -1 :
1992
        query = query.filter(Alert.status == status)
4394 rajveer 1993
    if timestamp:
1994
        query = query.filter(Alert.timestamp >= to_py_date(timestamp))
4412 rajveer 1995
    query = query.order_by(desc(Alert.timestamp))
483 rajveer 1996
    return query.all()
1997
 
4447 rajveer 1998
def add_alert(type, warehouseId, description):
4394 rajveer 1999
    alert = Alert()
2000
    alert.type = type
2001
    alert.status = 1
2002
    alert.description = description
2003
    alert.timestamp = datetime.datetime.now()
4447 rajveer 2004
    alert.warehouseId = warehouseId
4444 rajveer 2005
    session.commit()
766 rajveer 2006
 
4444 rajveer 2007
def mark_alerts_as_seen(warehouseId):
2008
    query = Alert.query.filter(Alert.warehouseId == warehouseId).filter(Alert.status == 1)
2009
    alerts = query.all()
2010
    for alert in alerts:
2011
        alert.status = 0    
2012
    session.commit()
2013
 
1596 ankur.sing 2014
def get_valid_order_count():
2851 chandransh 2015
    '''
2016
    Returns the number of orders which we processed. The reshipped orders are not
2017
    counted since there'll always be a new compensating order present.
2018
    '''
4682 rajveer 2019
    return Order.query.filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).filter(not_(Order.status.in_((OrderStatus.RTO_RESHIPPED, OrderStatus.DOA_INVALID_RESHIPPED, OrderStatus.DOA_VALID_RESHIPPED, OrderStatus.COD_VERIFICATION_FAILED)))).count()
1596 ankur.sing 2020
 
1627 ankur.sing 2021
def get_cust_count_with_successful_txn():
2851 chandransh 2022
    '''
2023
    Returns the number of distinct customers who have done successful transactions.
2024
    It uses the sqlalchemy func module to construct an efficient query.
2025
    '''
2026
    return session.query(func.count(distinct(Order.customer_id))).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).scalar()
1627 ankur.sing 2027
 
1730 ankur.sing 2028
def get_valid_orders_amount_range():
2851 chandransh 2029
    '''
2030
    Returns a list containing the minimum and maximum amount across all
2031
    orders placed with us. No need to consider reshippped orders for min/max
2032
    amount of orders.
2033
    '''
2034
    return session.query(func.min(Order.total_amount), func.max(Order.total_amount)).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).one()
1627 ankur.sing 2035
 
5874 rajveer 2036
def get_valid_orders(limit, onlyStore):
2851 chandransh 2037
    '''
2038
    Returns the last limit number of valid orders placed with us. Ignored the
2039
    limit if it's passed as 0. Raises an excpetion if the supplied limit is 
2040
    less than 0. 
2041
    '''
2042
    if limit < 0:
2043
        raise TransactionServiceException(101, "Invalid argument limit " + limit)
4662 rajveer 2044
    query = Order.query.filter(Order.status >= OrderStatus.COD_VERIFICATION_PENDING)
5874 rajveer 2045
    if onlyStore:
2046
        query = query.filter(Order.pickupStoreId != 0)
1886 ankur.sing 2047
    query = query.order_by(desc(Order.created_timestamp))
2851 chandransh 2048
    if limit != 0:
1886 ankur.sing 2049
        query = query.limit(limit)
2050
    return query.all()
2051
 
5527 anupam.sin 2052
def get_next_invoice_number(orderType):
2053
    if OrderType.B2Cbulk == orderType:
2054
        orderType = OrderType.B2C
2055
    entity_id = InvoiceIDGenerator.query.filter(InvoiceIDGenerator.orderType == orderType).with_lockmode("update").one()
2783 chandransh 2056
    invoice_number = entity_id.id + 1
2057
    entity_id.id = invoice_number
2058
    return invoice_number
2059
 
2536 chandransh 2060
def toggle_doa_flag(order_id):
2061
    order = get_order(order_id)
2062
    if(order.doaFlag):
2063
        order.doaFlag = False
2064
    else:
2065
        order.doaFlag = True
2066
    session.commit()
2067
    return order.doaFlag
2068
 
4454 rajveer 2069
def mark_order_doa_request_received(orderId):
2070
    order = get_order(orderId)
2071
    if order.status != OrderStatus.DELIVERY_SUCCESS:
2072
        return False
2073
    order.status = OrderStatus.DOA_REQUEST_RECEIVED
4459 rajveer 2074
    order.statusDescription = "DOA Request Received"
4454 rajveer 2075
    session.commit()
2076
    return True
2077
 
7645 anupam.sin 2078
def mark_order_doa_request_authorized(orderId, isAuthorized, fromStore, isReship):
4454 rajveer 2079
    order = get_order(orderId)
2080
    if order.status != OrderStatus.DOA_REQUEST_RECEIVED:
2081
        return False
2082
    if isAuthorized:
2083
        order.status = OrderStatus.DOA_REQUEST_AUTHORIZED
4459 rajveer 2084
        order.statusDescription = "DOA Request Authorized"
7645 anupam.sin 2085
        if order.source == 2:
2086
            if fromStore:
2087
                if isReship:
2088
                    new_order = __clone_order(order, False, False)
2089
                    order.reship_timestamp = datetime.datetime.now()
2090
                    order.new_order_id = new_order.id
2091
                else:
2092
                    sod = StoreOrderDetail.get_by(orderId = order.id)
2093
                    if sod.cashAmount > 0:
2094
                        __push_store_collection_to_hotspot(order, "RefundFromStore", -sod.cashAmount, 0)
2095
 
2096
                    if sod.cardAmount == 0:
2097
                        sod.payStatus = StorePaymentStatus.ADV_REFUNDED
2098
                    else:
2099
                        sod.payStatus = StorePaymentStatus.REFUND_REQUESTED
2100
 
2101
                    order.refund_timestamp = datetime.datetime.now()
2102
                    order.refunded_by = "CRM Outbound Team"
2103
                    sod.cashRefundAmount = sod.cashAmount
2104
                    sod.cardRefundAmount = sod.cardAmount
4454 rajveer 2105
    else:
2106
        order.status = OrderStatus.DELIVERY_SUCCESS
4459 rajveer 2107
        order.statusDescription = "Order delivered"
4454 rajveer 2108
    session.commit()
2109
    return True
2110
 
4488 rajveer 2111
def mark_order_return_request_received(orderId):
2112
    order = get_order(orderId)
2113
    if order.status != OrderStatus.DELIVERY_SUCCESS:
2114
        return False
2115
    order.status = OrderStatus.RET_REQUEST_RECEIVED
2116
    order.statusDescription = "Return Request Received"
2117
    session.commit()
2118
    return True
2119
 
7645 anupam.sin 2120
def mark_order_return_request_authorized(orderId, isAuthorized, fromStore, isReship):
4488 rajveer 2121
    order = get_order(orderId)
2122
    if order.status != OrderStatus.RET_REQUEST_RECEIVED:
2123
        return False
7645 anupam.sin 2124
 
4488 rajveer 2125
    if isAuthorized:
2126
        order.status = OrderStatus.RET_REQUEST_AUTHORIZED
2127
        order.statusDescription = "Return Request Authorized"
7645 anupam.sin 2128
        if order.source == 2:
2129
            if fromStore:
2130
                if isReship:
2131
                    new_order = __clone_order(order, False, False)
2132
                    order.reship_timestamp = datetime.datetime.now()
2133
                    order.new_order_id = new_order.id
2134
                else:
2135
                    sod = StoreOrderDetail.get_by(orderId = order.id)
2136
                    if sod.cashAmount > 0:
2137
                        __push_store_collection_to_hotspot(order, "RefundFromStore", -sod.cashAmount, 0)
2138
 
2139
                    if sod.cardAmount == 0:
2140
                        sod.payStatus = StorePaymentStatus.ADV_REFUNDED
2141
                    else:
2142
                        sod.payStatus = StorePaymentStatus.REFUND_REQUESTED
2143
 
2144
                    order.refund_timestamp = datetime.datetime.now()
2145
                    order.refunded_by = "CRM Outbound Team"
2146
                    sod.cashRefundAmount = sod.cashAmount
2147
                    sod.cardRefundAmount = sod.cardAmount
4488 rajveer 2148
    else:
2149
        order.status = OrderStatus.DELIVERY_SUCCESS
2150
        order.statusDescription = "Order delivered"
2151
    session.commit()
2152
    return True
2153
 
4579 rajveer 2154
def request_pickup_number(order_id, providerId):
2536 chandransh 2155
    order = get_order(order_id)
4495 rajveer 2156
    if order.status != OrderStatus.DELIVERY_SUCCESS and order.status != OrderStatus.DOA_REQUEST_AUTHORIZED and order.status != OrderStatus.RET_REQUEST_AUTHORIZED:
2536 chandransh 2157
        return False
7631 rajveer 2158
    if order.status == OrderStatus.RET_REQUEST_AUTHORIZED:
2159
        order.status = OrderStatus.RET_PICKUP_REQUEST_RAISED
2160
        order.statusDescription = "Pick up requested for RETURN"
2161
    else:
2162
        order.status = OrderStatus.DOA_PICKUP_REQUEST_RAISED
2163
        order.statusDescription = "Pick up requested for DOA"
2164
    order.doa_logistics_provider_id = providerId
2165
    session.commit()
2166
    return True
2536 chandransh 2167
 
4602 rajveer 2168
def authorize_pickup(order_id, pickup_number, providerId):
2536 chandransh 2169
    order = get_order(order_id)
4495 rajveer 2170
    if order.status not in [OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.RET_PICKUP_REQUEST_RAISED]:
2536 chandransh 2171
        return False
4815 phani.kuma 2172
    if order.doa_logistics_provider_id is not None:
2173
        providerId = order.doa_logistics_provider_id    #previously we are not storing this so data is taken from omdashboarduser
2536 chandransh 2174
    subject = 'Pickup details'
2175
    filename = "/tmp/" +  str(order.id) +".pdf" 
2176
    try:
5944 mandeep.dh 2177
        inventory_client = InventoryClient().get_client()
2178
        warehouse = inventory_client.getWarehouse(order.warehouse_id)
2536 chandransh 2179
 
2180
        logistics_client = LogisticsClient().get_client()
4602 rajveer 2181
        provider = logistics_client.getProvider(providerId)
2536 chandransh 2182
        provider_name = provider.name
2183
 
2184
        to_addr = order.customer_email
2185
        today = date.today().strftime("%d-%B-%Y (%A)")
2186
 
2187
        raw_message = '''
7663 anupam.sin 2188
        Dear %(customer_name)s,
7628 rajveer 2189
 
2190
        Would like to inform you that we have instructed %(provider_name)s to pick up the material from the below mentioned address on %(date)s. %(provider_name)s pickup request number is %(pickup_request_no)s.'
2191
 
2192
        Take a printout of the attachment in this mail which contains the delivery address and paste it on the packed parcel. Kindly keep the parcel ready.
2536 chandransh 2193
 
2194
        Pickup will happen from the below mentioned address:-
2195
 
2196
        %(customer_address)s
2197
 
2198
        Do let us know in case of any concerns
2199
 
2200
        Thanks & Regards
6029 rajveer 2201
        %(source_name)s Team
2536 chandransh 2202
        '''
2203
        message = dedent(raw_message) % {'customer_name' : order.customer_name,
2204
                                         'order_id' : order_id,
2205
                                         'provider_name' : provider_name,
2206
                                         'date': today,
2207
                                         'pickup_request_no' : pickup_number,
6029 rajveer 2208
                                         'customer_address' : __get_order_address(order),
2209
                                         'source_name' : source_name}
2536 chandransh 2210
        print message
2211
        __generate_return_advice(order, warehouse, provider, filename)
5966 rajveer 2212
        mail(help_user, help_password, [to_addr], subject, message, [get_attachment_part(filename)])
2536 chandransh 2213
        order.pickupRequestNo = pickup_number
4495 rajveer 2214
        if order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:
2215
            order.status = OrderStatus.RET_PICKUP_CONFIRMED
2216
            order.statusDescription = "RETURN pick up confirmed"
2217
        else:
2218
            order.status = OrderStatus.DOA_PICKUP_CONFIRMED
2219
            order.statusDescription = "DOA pick up confirmed"
2764 chandransh 2220
        order.doa_auth_timestamp = datetime.datetime.now()
2536 chandransh 2221
        session.commit()
2222
        return True
2223
    except Exception as e:
4234 rajveer 2224
        print sys.exc_info()
4506 phani.kuma 2225
        traceback.print_tb(sys.exc_info()[2])
2536 chandransh 2226
        return False
2227
    finally:
2228
        if os.path.exists(filename):
2229
            os.remove(filename)
2230
 
2764 chandransh 2231
def mark_doas_as_picked_up(provider_id, pickup_details):
2232
    for pickupNo, doa_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2233
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4452 rajveer 2234
        if order == None or order.status != OrderStatus.DOA_PICKUP_CONFIRMED:
2764 chandransh 2235
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2236
            continue
2237
        order.status = OrderStatus.DOA_RETURN_IN_TRANSIT
2238
        order.statusDescription = "DOA picked up by Courier Company"
2239
        order.doa_pickup_timestamp = doa_pickup_timestamp
2240
    session.commit()
2241
 
4910 phani.kuma 2242
def get_doas_not_picked_up(provider_id):
2764 chandransh 2243
    current_time = datetime.datetime.now()
2244
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2245
    orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.DOA_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()
2764 chandransh 2246
    return orders_not_picked_up
2247
 
4741 phani.kuma 2248
def mark_return_orders_as_picked_up(provider_id, pickup_details):
2249
    for pickupNo, return_order_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2250
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4741 phani.kuma 2251
        if order == None or order.status != OrderStatus.RET_PICKUP_CONFIRMED:
2252
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2253
            continue
2254
        order.status = OrderStatus.RET_RETURN_IN_TRANSIT
2255
        order.statusDescription = "Return order picked up by Courier Company"
2256
        order.doa_pickup_timestamp = return_order_pickup_timestamp
2257
    session.commit()
2258
 
4910 phani.kuma 2259
def get_return_orders_not_picked_up(provider_id):
4741 phani.kuma 2260
    current_time = datetime.datetime.now()
2261
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2262
    orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.RET_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()
4741 phani.kuma 2263
    return orders_not_picked_up
2264
 
4479 rajveer 2265
def receive_return(order_id, receiveCondition):
2591 chandransh 2266
    order = get_order(order_id)
7199 amar.kumar 2267
    scanFreebie = False
4365 mandeep.dh 2268
 
4452 rajveer 2269
    if order.status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.DOA_RETURN_IN_TRANSIT]:
4479 rajveer 2270
        if receiveCondition == 0:
2271
            order.status = OrderStatus.DOA_RECEIVED_PRESTINE
2272
            order.statusDescription = "DOA package received"
2273
        elif receiveCondition == 1:
2274
            order.status = OrderStatus.DOA_RECEIVED_DAMAGED
2275
            order.statusDescription = "DOA received damaged"
2276
        elif receiveCondition == 2:
2277
            order.status = OrderStatus.DOA_LOST_IN_TRANSIT
2278
            order.statusDescription = "DOA lost in transit"
2764 chandransh 2279
        order.received_return_timestamp = datetime.datetime.now()
4495 rajveer 2280
    elif order.status in [OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_RETURN_IN_TRANSIT]:
2281
        if receiveCondition == 0:
2282
            order.status = OrderStatus.RET_RECEIVED_PRESTINE
2283
            order.statusDescription = "RETURN package received"
2284
        elif receiveCondition == 1:
2285
            order.status = OrderStatus.RET_RECEIVED_DAMAGED
2286
            order.statusDescription = "RETURN received damaged"
2287
        elif receiveCondition == 2:
2288
            order.status = OrderStatus.RET_LOST_IN_TRANSIT
2289
            order.statusDescription = "RETURN lost in transit"
2290
        order.received_return_timestamp = datetime.datetime.now()
4484 rajveer 2291
    elif order.status == OrderStatus.RTO_IN_TRANSIT :
4486 rajveer 2292
        if receiveCondition == 0:
2293
            order.status = OrderStatus.RTO_RECEIVED_PRESTINE
4515 mandeep.dh 2294
            order.statusDescription = "Returned to origin"
4486 rajveer 2295
        elif receiveCondition == 1:
2296
            order.status = OrderStatus.RTO_RECEIVED_DAMAGED
2297
            order.statusDescription = "RTO received damaged"
2298
        elif receiveCondition == 2:
2299
            order.status = OrderStatus.RTO_LOST_IN_TRANSIT
2300
            order.statusDescription = "RTO lost in transit"
2764 chandransh 2301
        order.received_return_timestamp = datetime.datetime.now()
7199 amar.kumar 2302
        if order.freebieItemId:
2303
            scanFreebie = True
2616 chandransh 2304
    else:
2591 chandransh 2305
        return False
5110 mandeep.dh 2306
 
2307
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2308
    inventoryClient = InventoryClient().get_client()
2309
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6763 amar.kumar 2310
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5361 mandeep.dh 2311
        scanMap = {
2312
            OrderStatus.RTO_RECEIVED_PRESTINE : ScanType.SALE_RET,
2313
            OrderStatus.RTO_RECEIVED_DAMAGED  : ScanType.SALE_RET_UNUSABLE,
2314
            OrderStatus.RTO_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT,
2315
            OrderStatus.DOA_RECEIVED_PRESTINE : ScanType.DOA_IN,
2316
            OrderStatus.DOA_RECEIVED_DAMAGED  : ScanType.DOA_IN,
2317
            OrderStatus.DOA_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT
2318
        }
5110 mandeep.dh 2319
 
5419 mandeep.dh 2320
        if scanMap.has_key(order.status):
2321
            scanType = scanMap[order.status]
5361 mandeep.dh 2322
            lineitem = order.lineitems[0]
5944 mandeep.dh 2323
            catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2324
            item = catalogClient.getItem(lineitem.item_id)
2325
            warehouseClient = WarehouseClient().get_client()
6763 amar.kumar 2326
            if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2327
                if item.type == ItemType.SERIALIZED:
2328
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2329
                else:
2330
                    warehouseClient.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2331
            if warehouse.billingType == BillingType.OURS_EXTERNAL and scanType == ScanType.SALE_RET:
2332
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)
7199 amar.kumar 2333
            if scanFreebie:
7292 amar.kumar 2334
                warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, scanType)
7645 anupam.sin 2335
 
2336
    session.commit()  
2591 chandransh 2337
    return True
2338
 
2339
def validate_doa(order_id, is_valid):
2340
    order = get_order(order_id)
4452 rajveer 2341
    if order.status != OrderStatus.DOA_RECEIVED_PRESTINE:
2591 chandransh 2342
        return False
2343
    if is_valid:
2609 chandransh 2344
        order.status = OrderStatus.DOA_CERT_VALID
2345
        order.statusDescription = "DOA Certificate Valid"
2591 chandransh 2346
    else:
2347
        order.status = OrderStatus.DOA_CERT_INVALID
2348
        order.statusDescription = "DOA Certificate Invalid"
3578 mandeep.dh 2349
        update_trust_level(order)
2591 chandransh 2350
    session.commit()
2351
    return True
2352
 
4495 rajveer 2353
def validate_return_product(order_id, is_usable):
2354
    order = get_order(order_id)
2355
    if order.status != OrderStatus.RET_RECEIVED_PRESTINE:
2356
        return False
5110 mandeep.dh 2357
 
2358
    scanType = ScanType.SALE_RET_UNUSABLE
4495 rajveer 2359
    if is_usable:
2360
        order.status = OrderStatus.RET_PRODUCT_USABLE
2361
        order.statusDescription = "Return product usable"
5110 mandeep.dh 2362
        scanType = ScanType.SALE_RET
4495 rajveer 2363
    else:
2364
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE
2365
        order.statusDescription = "Return product unusable"
2366
        update_trust_level(order)
2367
    session.commit()
5110 mandeep.dh 2368
 
2369
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2370
    inventoryClient = InventoryClient().get_client()
2371
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2372
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5110 mandeep.dh 2373
        lineitem = order.lineitems[0]
5944 mandeep.dh 2374
        catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2375
        item = catalogClient.getItem(lineitem.item_id)
5110 mandeep.dh 2376
        warehouse_client = WarehouseClient().get_client()
6786 amar.kumar 2377
        if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2378
            if item.type == ItemType.SERIALIZED:
2379
                warehouse_client.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2380
            else:
2381
                warehouse_client.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2382
        if scanType == ScanType.SALE_RET and warehouse.billingType == BillingType.OURS_EXTERNAL:
2383
            warehouse_client.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)        
4495 rajveer 2384
    return True
2385
 
2628 chandransh 2386
def reship_order(order_id):
2387
    """
4484 rajveer 2388
    If the order is in RTO_RECEIVED_PRESTINE or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2389
        1. Creates a new order for processing in the BILLED state. All billing information is saved.
4484 rajveer 2390
        2. Marks the current order as one of the final states RTO_RESHIPPED and DOA_INVALID_RESHIPPED depending on what state the order started in.
2628 chandransh 2391
 
2392
    If the order is in DOA_CERT_VALID state, it does the following:
2393
        1. Creates a new order for processing in the SUBMITTED_FOR_PROCESSING state.
2394
        2. Creates a return order for the warehouse executive to return the DOA material.
4452 rajveer 2395
        3. Marks the current order as the final DOA_VALID_RESHIPPED state.
2628 chandransh 2396
 
2397
    Returns the id of the newly created order.
2398
 
2399
    Throws an exception if the order with the given id couldn't be found.
2400
 
2401
    Parameters:
2402
     - orderId
2403
    """
2404
    order = get_order(order_id)
7645 anupam.sin 2405
    alreadyReshipped = False
7663 anupam.sin 2406
 
2407
    #If this order was from store and it was already marked refunded then this order 
2408
    #should not be reshipped.
2409
    if order.source == 2:
2410
        sod = StoreOrderDetail.get_by(orderId = order.id)
2411
        if sod.payStatus in (StorePaymentStatus.ADV_REFUNDED , StorePaymentStatus.REFUND_INITIATED, \
2412
                                          StorePaymentStatus.REFUND_REQUESTED, StorePaymentStatus.REFUNDED):
2413
            raise TransactionServiceException(112, "This order should be refunded")
2414
 
2415
    #If this order was from store and a new order Id has already been set then it means that
2416
    #a new order corresponding to this order has already been shipped.
7645 anupam.sin 2417
    if order.source == 2 and order.new_order_id:
2418
        alreadyReshipped = True
4484 rajveer 2419
    if order.status == OrderStatus.RTO_RECEIVED_PRESTINE:
2420
        order.status = OrderStatus.RTO_RESHIPPED
2628 chandransh 2421
        order.statusDescription = "Order Reshipped"
7645 anupam.sin 2422
        if not alreadyReshipped:
2423
            new_order = __clone_order(order, True, order.cod)
3578 mandeep.dh 2424
        update_trust_level(order)
6735 amar.kumar 2425
        __scan_for_reship_order(order_id, new_order)
4486 rajveer 2426
    elif order.status == OrderStatus.RTO_RECEIVED_DAMAGED:
2427
        order.status = OrderStatus.RTO_DAMAGED_RESHIPPED
2428
        order.statusDescription = "Order Reshipped Received Damaged"
7645 anupam.sin 2429
        if not alreadyReshipped:
2430
            new_order = __clone_order(order, False, order.cod)
2431
        ret_order = __create_return_order(order)
4486 rajveer 2432
    elif order.status == OrderStatus.RTO_LOST_IN_TRANSIT:
2433
        order.status = OrderStatus.RTO_LOST_IN_TRANSIT_RESHIPPED
2434
        order.statusDescription = "Order Reshipped Lost In Transit"
7645 anupam.sin 2435
        if not alreadyReshipped:
2436
            new_order = __clone_order(order, False, order.cod)
4662 rajveer 2437
    elif order.status == OrderStatus.LOST_IN_TRANSIT:
2438
        order.status = OrderStatus.LOST_IN_TRANSIT_RESHIPPED
2439
        order.statusDescription = "Order Reshipped Lost In Transit"
7645 anupam.sin 2440
        if not alreadyReshipped:
2441
            new_order = __clone_order(order, False, order.cod)
2628 chandransh 2442
    elif order.status == OrderStatus.DOA_CERT_INVALID:
2443
        order.status = OrderStatus.DOA_INVALID_RESHIPPED
2444
        order.statusDescription = "Order Reshipped"
7645 anupam.sin 2445
        if not alreadyReshipped:
2446
            new_order = __clone_order(order, True, False)
6735 amar.kumar 2447
        __scan_for_reship_order(order_id, new_order)
2628 chandransh 2448
    elif order.status == OrderStatus.DOA_CERT_VALID:
4452 rajveer 2449
        order.status = OrderStatus.DOA_VALID_RESHIPPED
2628 chandransh 2450
        order.statusDescription = "Order Reshipped"
7645 anupam.sin 2451
        if not alreadyReshipped:
2452
            new_order = __clone_order(order, False, False)
2453
        ret_order = __create_return_order(order)
4479 rajveer 2454
    elif order.status == OrderStatus.DOA_RECEIVED_DAMAGED:
2455
        order.status = OrderStatus.DOA_RESHIPPED_RCVD_DAMAGED
2456
        order.statusDescription = "Order Reshipped Received Damaged"
7645 anupam.sin 2457
        if not alreadyReshipped:
2458
            new_order = __clone_order(order, False, False)
2459
        ret_order = __create_return_order(order)
4479 rajveer 2460
    elif order.status == OrderStatus.DOA_LOST_IN_TRANSIT:
2461
        order.status = OrderStatus.DOA_RESHIPPED_LOST_IN_TRANSIT
2462
        order.statusDescription = "Order Reshipped Lost In Transit"
7645 anupam.sin 2463
        if not alreadyReshipped:
2464
            new_order = __clone_order(order, False, False)
4614 rajveer 2465
    elif order.status == OrderStatus.RET_PRODUCT_USABLE:
2466
        order.status = OrderStatus.RET_PRODUCT_USABLE_RESHIPPED
4495 rajveer 2467
        order.statusDescription = "Order Reshipped"
7645 anupam.sin 2468
        if not alreadyReshipped:
2469
            new_order = __clone_order(order, False, False)
4614 rajveer 2470
    elif order.status == OrderStatus.RET_PRODUCT_UNUSABLE:
2471
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE_RESHIPPED
4495 rajveer 2472
        order.statusDescription = "Order Reshipped"
7645 anupam.sin 2473
        if not alreadyReshipped:
2474
            new_order = __clone_order(order, False, False)
2475
        ret_order = __create_return_order(order)
4495 rajveer 2476
    elif order.status == OrderStatus.RET_RECEIVED_DAMAGED:
2477
        order.status = OrderStatus.RET_RESHIPPED_RCVD_DAMAGED
2478
        order.statusDescription = "Order Reshipped Received Damaged"
7645 anupam.sin 2479
        if not alreadyReshipped:
2480
            new_order = __clone_order(order, False, False)
2481
        ret_order = __create_return_order(order)
4495 rajveer 2482
    elif order.status == OrderStatus.RET_LOST_IN_TRANSIT:
2483
        order.status = OrderStatus.RET_RESHIPPED_LOST_IN_TRANSIT
2484
        order.statusDescription = "Order Reshipped Lost In Transit"
7645 anupam.sin 2485
        if not alreadyReshipped:
2486
            new_order = __clone_order(order, False, False)
2628 chandransh 2487
    else:
2488
        raise TransactionServiceException(112, "This order can't be reshipped")
2489
 
7645 anupam.sin 2490
    if not alreadyReshipped:
2491
        order.reship_timestamp = datetime.datetime.now()
2492
        order.new_order_id = new_order.id
2493
        session.commit()
2494
        return new_order.id
2495
    else:
7663 anupam.sin 2496
        session.commit()
7645 anupam.sin 2497
        return order.new_order_id
2628 chandransh 2498
 
2499
 
6735 amar.kumar 2500
def __scan_for_reship_order(order_id, new_order):
2501
    inventoryClient = InventoryClient().get_client()
2502
    warehouse = inventoryClient.getWarehouse(new_order.warehouse_id)
2503
    if warehouse.billingType == BillingType.OURS:
2504
        warehouseClient = WarehouseClient().get_client()
2505
        inventoryItem = warehouseClient.getInventoryItemFromOrder(order_id)
2506
        warehouseClient.scanForOrder(inventoryItem, ScanType.SALE, new_order.lineitems[0].quantity, new_order.id, new_order.fulfilmentWarehouseId, new_order.warehouse_id)
7199 amar.kumar 2507
    if order.freebieItemId:
2508
        warehouseClient = WarehouseClient().get_client()
2509
        inventoryItem = warehouseClient.reshipfreebie(order_id, new_order.id, new_order.freebieItemId, ScanType.SALE)
6735 amar.kumar 2510
 
3226 chandransh 2511
def refund_order(order_id, refunded_by, reason):
2628 chandransh 2512
    """
4484 rajveer 2513
    If the order is in RTO_RECEIVED_PRESTINE, DOA_CERT_VALID or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2514
        1. Creates a refund request for batch processing.
2515
        2. Creates a return order for the warehouse executive to return the shipped material.
4484 rajveer 2516
        3. Marks the current order as RTO_REFUNDED, DOA_VALID_REFUNDED or DOA_INVALID_REFUNDED final states.
2628 chandransh 2517
 
2518
    If the order is in SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2519
        1. Creates a refund request for batch processing.
3226 chandransh 2520
        2. Cancels the reservation of the item in the warehouse.
2521
        3. Marks the current order as the REFUNDED final state.
2628 chandransh 2522
 
3226 chandransh 2523
    For all COD orders, if the order is in INIT, SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2524
        1. Cancels the reservation of the item in the warehouse.
2525
        2. Marks the current order as CANCELED.
2526
 
2527
    In all cases, it updates the reason for cancellation or refund and the person who performed the action.
2528
 
2529
    Returns True if it is successful, False otherwise.
2628 chandransh 2530
 
2531
    Throws an exception if the order with the given id couldn't be found.
2532
 
2533
    Parameters:
3226 chandransh 2534
     - order_id
2535
     - refunded_by
2536
     - reason
2628 chandransh 2537
    """
3414 chandransh 2538
    logging.info("Refunding order id: " + str(order_id))
2628 chandransh 2539
    order = get_order(order_id)
3186 chandransh 2540
 
7663 anupam.sin 2541
    #if this order is from store and a new order for it has already been reshipped then
2542
    #this order cannot be refunded.
2543
    if order.source == 2 and order.new_order_id:
2544
        raise TransactionServiceException(112, "This order should be marked reship")
2545
 
3226 chandransh 2546
    if order.cod:
3414 chandransh 2547
        logging.info("Refunding COD order with status " + str(order.status))
4662 rajveer 2548
        status_transition = { OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2549
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2550
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2551
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2552
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2553
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2554
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2555
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2556
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2557
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2558
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2559
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2560
                     OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.COD_VERIFICATION_FAILED,
2561
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2562
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2563
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2564
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2565
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2566
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2567
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2568
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST
3366 chandransh 2569
                     }
2570
        if order.status not in status_transition.keys():
2571
            raise TransactionServiceException(114, "This order can't be refunded")
7386 anupam.sin 2572
 
5199 mandeep.dh 2573
        if order.status in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3226 chandransh 2574
            __update_inventory_reservation(order)
2575
            order.statusDescription = "Order Cancelled"
3415 chandransh 2576
        elif order.status == OrderStatus.BILLED:
3413 chandransh 2577
            __create_return_order(order)
2578
            order.statusDescription = "Order Cancelled"
4486 rajveer 2579
        elif order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT]:
5386 phani.kuma 2580
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2581
                __create_return_order(order)
4486 rajveer 2582
            order.statusDescription = "RTO Refunded"
4662 rajveer 2583
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2584
            #__create_return_order(order)
4662 rajveer 2585
            order.statusDescription = "Lost in Transit Refunded"
4479 rajveer 2586
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2587
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2588
                __create_return_order(order)
3226 chandransh 2589
            __create_refund(order)
4495 rajveer 2590
            order.statusDescription = "DOA Refunded"
2591
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2592
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2593
                __create_return_order(order)
4495 rajveer 2594
            __create_refund(order)
2595
            order.statusDescription = "Return Refunded"
4247 rajveer 2596
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5199 mandeep.dh 2597
            if order.previousStatus in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
4247 rajveer 2598
                __update_inventory_reservation(order)
2599
                order.statusDescription = "Order Cancelled on customer request"
2600
            elif order.previousStatus == OrderStatus.BILLED:
2601
                __create_return_order(order)
2602
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2603
                order.received_return_timestamp = datetime.datetime.now()
3226 chandransh 2604
    else:
4662 rajveer 2605
        status_transition = {OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2606
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2607
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2608
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2609
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2610
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2611
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2612
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2613
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2614
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2615
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2616
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2617
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2618
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2619
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2620
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2621
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2622
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2623
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2624
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,
2625
                     OrderStatus.PAYMENT_FLAGGED : OrderStatus.PAYMENT_FLAGGED_DENIED
3366 chandransh 2626
                     }
2627
        if order.status not in status_transition.keys():
2628
            raise TransactionServiceException(114, "This order can't be refunded")
2629
 
4495 rajveer 2630
        if order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT] :
5386 phani.kuma 2631
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2632
                __create_return_order(order)
3226 chandransh 2633
            __create_refund(order)
4495 rajveer 2634
            order.statusDescription = "RTO Refunded"
7597 kshitij.so 2635
            #Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
2636
            try: 
2637
                crmServiceClient = CRMClient().get_client()
2638
                ticket =Ticket()
2639
                activity = Activity()
2640
 
2641
                description = "Creating Ticket for " + order.statusDescription + " Order"
2642
                ticket.creatorId = 1
2643
                ticket.assigneeId = 34
2644
                ticket.category = TicketCategory.RTO_REFUND
2645
                ticket.priority = TicketPriority.MEDIUM
2646
                ticket.status = TicketStatus.OPEN
2647
                ticket.description = description
2648
                ticket.orderId = order.id
2649
 
2650
                activity.creatorId = 1
2651
                activity.ticketAssigneeId = ticket.assigneeId
2652
                activity.type = ActivityType.OTHER
2653
                activity.description = description
2654
                activity.ticketCategory = ticket.category
2655
                activity.ticketDescription = ticket.description
2656
                activity.ticketPriority = ticket.priority
2657
                activity.ticketStatus = ticket.status
2658
 
2659
                ticket.customerId= order.customer_id
2660
                ticket.customerEmailId = order.customer_email
2661
                ticket.customerMobileNumber = order.customer_mobilenumber
2662
                ticket.customerName = order.customer_name
2663
                activity.customerId = ticket.customerId
2664
                activity.customerEmailId = order.customer_email
2665
                activity.customerMobileNumber = order.customer_mobilenumber
2666
                activity.customerName = order.customer_name
2667
 
2668
                crmServiceClient.insertTicket(ticket, activity)
2669
 
2670
            except:
2671
                print "Ticket for RTO Refund is not created."
2672
            #End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
4662 rajveer 2673
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2674
            #__create_return_order(order)
4662 rajveer 2675
            __create_refund(order)
2676
            order.statusDescription = "Lost in Transit Refunded"
4495 rajveer 2677
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2678
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2679
                __create_return_order(order)
4495 rajveer 2680
            __create_refund(order)
2681
            order.statusDescription = "DOA Refunded"
2682
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2683
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2684
                __create_return_order(order)
4495 rajveer 2685
            __create_refund(order)
2686
            order.statusDescription = "Return Refunded"
5199 mandeep.dh 2687
        elif order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3226 chandransh 2688
            __update_inventory_reservation(order)
2689
            order.statusDescription = "Order Refunded"
4247 rajveer 2690
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5272 mandeep.dh 2691
            if order.previousStatus in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.PAYMENT_FLAGGED, OrderStatus.ACCEPTED]:
4672 rajveer 2692
                if order.previousStatus == OrderStatus.ACCEPTED:
2693
                    __create_refund(order)
4247 rajveer 2694
                __update_inventory_reservation(order)
2695
                order.statusDescription = "Order Cancelled on customer request"
2696
            elif order.previousStatus == OrderStatus.BILLED:
2697
                __create_return_order(order)
2698
                __create_refund(order)
2699
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2700
                order.received_return_timestamp = datetime.datetime.now()
4247 rajveer 2701
        elif order.status == OrderStatus.PAYMENT_FLAGGED:
2702
            __update_inventory_reservation(order)
2703
            order.statusDescription = "Order Cancelled due to payment flagged"
3195 chandransh 2704
 
4873 mandeep.dh 2705
    # For orders that are cancelled after being billed, we need to scan in the scanned out
2706
    # inventory item and change availability accordingly
5944 mandeep.dh 2707
    inventoryClient = InventoryClient().get_client()
2708
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2709
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
4873 mandeep.dh 2710
        if order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH] or (order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED and order.previousStatus in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]):
2711
            lineitem = order.lineitems[0]
5944 mandeep.dh 2712
            catalogClient = CatalogClient().get_client()
5177 mandeep.dh 2713
            item = catalogClient.getItem(lineitem.item_id)
5361 mandeep.dh 2714
            warehouseClient = WarehouseClient().get_client()
6786 amar.kumar 2715
            if warehouse.billingType == BillingType.OURS:
2716
                if ItemType.SERIALIZED == item.type:
2717
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, ScanType.SALE_RET, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2718
                else:
2719
                    warehouseClient.scanForOrder(None, ScanType.SALE_RET, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2720
            if warehouse.billingType == BillingType.OURS_EXTERNAL:
2721
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)            
4873 mandeep.dh 2722
 
7417 rajveer 2723
    if order.source == 2 and order.status in (OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW, OrderStatus.CANCEL_REQUEST_CONFIRMED):
7393 anupam.sin 2724
        storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == order.id).filter(StoreOrderDetail.storeId == order.storeId).first()
7611 anupam.sin 2725
 
2726
        if order.created_timestamp.date() == datetime.datetime.now().date() and storeOrderDetail.cardType != "debit":
7423 anupam.sin 2727
            __push_store_collection_to_hotspot(order, "RefundFromStore", -storeOrderDetail.cashRefundAmount, -storeOrderDetail.cardRefundAmount)
7393 anupam.sin 2728
            storeOrderDetail.payStatus = StorePaymentStatus.ADV_REFUNDED
2729
        else:
7611 anupam.sin 2730
            if storeOrderDetail.cardRefundAmount == 0:
7423 anupam.sin 2731
                storeOrderDetail.payStatus = StorePaymentStatus.ADV_REFUNDED
7393 anupam.sin 2732
            else:
7423 anupam.sin 2733
                storeOrderDetail.payStatus = StorePaymentStatus.REFUND_REQUESTED
2734
 
2735
            if storeOrderDetail.cashRefundAmount > 0:
2736
                __push_store_collection_to_hotspot(order, "RefundFromStore", -storeOrderDetail.cashRefundAmount, 0)
2737
 
7645 anupam.sin 2738
    elif order.source == 2 and order.status in (OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, \
2739
                                                OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, \
2740
                                                OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT ,\
2741
                                                OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, \
2742
                                                OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT):
2743
        storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == order.id).filter(StoreOrderDetail.storeId == order.storeId).first()
2744
        if storeOrderDetail.payStatus not in (StorePaymentStatus.ADV_REFUNDED , StorePaymentStatus.REFUND_INITIATED, \
2745
                                          StorePaymentStatus.REFUND_REQUESTED, StorePaymentStatus.REFUNDED):
2746
            storeOrderDetail.payStatus = StorePaymentStatus.REFUND_REQUESTED
2747
        else:
2748
            order.status = status_transition[order.status]
2749
            order.refund_reason = reason
2750
            session.commit()
2751
            return True
2752
 
3195 chandransh 2753
    order.status = status_transition[order.status]
2754
    order.refund_timestamp = datetime.datetime.now()
3226 chandransh 2755
    order.refunded_by = refunded_by
2756
    order.refund_reason = reason
2628 chandransh 2757
    session.commit()
2758
    return True
2759
 
3186 chandransh 2760
def __update_inventory_reservation(order):
3191 chandransh 2761
    '''
2762
    Reduce the reservation count for all line items of the given order.
2763
    '''
3186 chandransh 2764
    try:
5944 mandeep.dh 2765
        inventoryClient = InventoryClient().get_client()
3186 chandransh 2766
        for lineitem in order.lineitems:
5966 rajveer 2767
            inventoryClient.reduceReservationCount(lineitem.item_id, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
3186 chandransh 2768
    except:
2769
        print "Unable to reduce reservation count"
2770
 
4220 rajveer 2771
def __clone_order(order, should_copy_billing_info, is_cod):
2628 chandransh 2772
    current_time = datetime.datetime.now()
2773
    new_order = Order()
2774
    new_order.customer_id = order.customer_id
2775
    new_order.customer_name = order.customer_name
2776
    new_order.customer_city = order.customer_city
2777
    new_order.customer_state = order.customer_state
2778
    new_order.customer_mobilenumber = order.customer_mobilenumber
2779
    new_order.customer_pincode = order.customer_pincode
2780
    new_order.customer_address1 = order.customer_address1
2781
    new_order.customer_address2 = order.customer_address2
2782
    new_order.customer_email = order.customer_email
2783
    new_order.total_amount = order.total_amount
6318 rajveer 2784
    new_order.gvAmount = order.gvAmount
2628 chandransh 2785
    new_order.total_weight = order.total_weight
2786
    new_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
2787
    new_order.statusDescription = 'Submitted for Processing'
2788
    new_order.created_timestamp = current_time
5062 varun.gupt 2789
    new_order.originalOrderId = order.originalOrderId if order.originalOrderId is not None else order.id 
2628 chandransh 2790
 
2791
    new_order.transaction = order.transaction
4220 rajveer 2792
    new_order.cod = is_cod
5527 anupam.sin 2793
    new_order.orderType = order.orderType
2628 chandransh 2794
    for line_item in order.lineitems:
2795
        litem = LineItem()
2796
        litem.item_id = line_item.item_id
2797
        litem.productGroup = line_item.productGroup
2798
        litem.brand = line_item.brand
2799
        if line_item.model_number:
2800
            litem.model_number = line_item.model_number
2801
        if line_item.model_name:    
2802
            litem.model_name = line_item.model_name
2803
        if line_item.color:
2804
            litem.color = line_item.color
2805
        if line_item.extra_info:
2806
            litem.extra_info = line_item.extra_info
2807
        litem.quantity = line_item.quantity
2808
        litem.unit_price = line_item.unit_price
2809
        litem.unit_weight = line_item.unit_weight
2810
        litem.total_price = line_item.total_price
2811
        litem.total_weight = line_item.total_weight
2812
        litem.transfer_price = line_item.transfer_price
6751 amar.kumar 2813
        litem.nlc = line_item.nlc
4840 mandeep.dh 2814
        litem.dealText = line_item.dealText
6423 amit.gupta 2815
        litem.vatRate = line_item.vatRate
2628 chandransh 2816
        litem.order = new_order
6912 anupam.sin 2817
 
2818
    if order.insurer > 0:
2819
        new_order.insurer = order.insurer
2820
        new_order.insuranceAmount = order.insuranceAmount
2821
        newDetail = InsuranceDetailForOrder()
2822
        oldDetail = InsuranceDetailForOrder.get_by(order_id = order.id)
2823
        newDetail.dob = oldDetail.dob
2824
        newDetail.guardianName = oldDetail.guardianName
2825
        newDetail.order = new_order
2826
 
2628 chandransh 2827
    logistics_client = LogisticsClient().get_client()
2828
    item_id = new_order.lineitems[0].item_id
5785 mandeep.dh 2829
    logistics_info = logistics_client.getLogisticsInfo(new_order.customer_pincode, item_id, is_cod, PickUpType.COURIER) #TODO: We should be able to pass another flag to suggest ignoring the inventory situation.
6726 rajveer 2830
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
2628 chandransh 2831
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
6726 rajveer 2832
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime + logistics_info.deliveryDelay))
2628 chandransh 2833
    new_order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 2834
    new_order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
2628 chandransh 2835
    new_order.logistics_provider_id = logistics_info.providerId
2836
    new_order.airwaybill_no = logistics_info.airway_billno
2837
    new_order.tracking_id = new_order.airwaybill_no
7564 rajveer 2838
    new_order.source = order.source
6726 rajveer 2839
 
2840
    order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2841
    new_order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 2842
    new_order.promised_delivery_time = new_order.expected_delivery_time
6629 anupam.sin 2843
    new_order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2844
    new_order.promised_shipping_time = new_order.expected_shipping_time
2845
 
2628 chandransh 2846
    if should_copy_billing_info:
5388 phani.kuma 2847
        new_order.vendorId = order.vendorId
2628 chandransh 2848
        new_order.invoice_number = order.invoice_number
2849
        new_order.billed_by = order.billed_by
2850
        new_order.warehouse_id = order.warehouse_id
5110 mandeep.dh 2851
        new_order.fulfilmentWarehouseId = order.fulfilmentWarehouseId
5620 mandeep.dh 2852
        new_order.jacket_number = order.jacket_number
2853
        new_order.lineitems[0].serial_number = order.lineitems[0].serial_number
2854
        new_order.lineitems[0].item_number   = order.lineitems[0].item_number
2628 chandransh 2855
        new_order.accepted_timestamp = current_time
2856
        new_order.billing_timestamp = current_time    
2857
        new_order.status = OrderStatus.BILLED
2858
        new_order.statusDescription = 'Order Billed'
7645 anupam.sin 2859
        session.commit()
5966 rajveer 2860
    else:
2861
        session.commit()       
5944 mandeep.dh 2862
        inventoryClient = InventoryClient().get_client()
5966 rajveer 2863
        inventoryClient.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, new_order.id, to_java_date(new_order.created_timestamp), to_java_date(new_order.promised_shipping_time), new_order.lineitems[0].quantity)
7645 anupam.sin 2864
 
2865
    if order.source == 2:
2866
        new_order.advanceAmount = order.advanceAmount
2867
        new_order.storeId = order.storeId   
2868
        oldSod = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == order.id).filter(StoreOrderDetail.storeId == order.storeId).first()
2869
        newSod = StoreOrderDetail()
2870
        newSod.orderId = new_order.id
2871
        newSod.storeId = oldSod.storeId
2872
        newSod.advanceAmount = oldSod.advanceAmount
2873
        newSod.approvalCode = oldSod.approvalCode
2874
        newSod.cardAmount = oldSod.cardAmount
2875
        newSod.cashAmount = oldSod.cashAmount
2876
        newSod.cashRefundAmount = oldSod.cashRefundAmount
2877
        newSod.cardRefundAmount = oldSod.cardRefundAmount
2878
        newSod.edcBank = oldSod.edcBank
2879
        newSod.payStatus = oldSod.payStatus
2880
        newSod.cardType = oldSod.cardType 
2881
        session.commit()
2882
 
2628 chandransh 2883
    return new_order
2884
 
2885
def __create_return_order(order):
2687 chandransh 2886
    ret_order = ReturnOrder(order)
2628 chandransh 2887
    return ret_order
2888
 
2889
def __create_refund(order):
4078 chandransh 2890
    payment_client = PaymentClient().get_client()
2891
    payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
2747 chandransh 2892
    return
2628 chandransh 2893
 
2536 chandransh 2894
def __get_order_address(order):
2895
    address = order.customer_name + "\n" + order.customer_address1 + "\n"
2896
    if order.customer_address2:
2897
        address = address + order.customer_address2 + "\n"
2898
    address = address + order.customer_city + "\n"
2899
    address = address + order.customer_state + "\n"
2900
    address = address + "PIN " + order.customer_pincode + "\n"
2901
    address = address + "Phone: " + order.customer_mobilenumber
2902
    return address
2903
 
7428 rajveer 2904
def __get_order_address_html(order):
7430 rajveer 2905
    address = order.customer_name + ", " + order.customer_address1 + ", "
7428 rajveer 2906
    if order.customer_address2:
7430 rajveer 2907
        address = address + order.customer_address2 + ", "
2908
    address = address + order.customer_city + ", "
2909
    address = address + order.customer_state + ", "
2910
    address = address + "PIN " + order.customer_pincode + "."
7428 rajveer 2911
    return address
2912
 
5767 rajveer 2913
def __get_store_address(store):
2914
    address = store.name + "\n" + store.line1 + "\n"
2915
    if store.line2:
2916
        address = address + store.line2 + "\n"
2917
    address = address + store.city + "\n"
2918
    address = address + store.state + "\n"
5802 rajveer 2919
    address = address + "PIN - " + store.pin + "\n"
5793 rajveer 2920
    if store.phone:
5802 rajveer 2921
        address = address + "Phone - " + store.phone + "\n"
5855 rajveer 2922
    address = address +  "Store timings - 11AM to 8PM (7 days)\n"
5767 rajveer 2923
    return address
2924
 
5793 rajveer 2925
def __get_store_address_html(store):
2926
    address = store.name + "<br>" + store.line1 + "<br>"
2927
    if store.line2:
2928
        address = address + store.line2 + "<br>"
2929
    address = address + store.city + "<br>"
2930
    address = address + store.state + "<br>"
5802 rajveer 2931
    address = address + "PIN - " + store.pin + "<br>"
5793 rajveer 2932
    if store.phone:
5802 rajveer 2933
        address = address + "Phone - " + store.phone + "<br>"
5855 rajveer 2934
    address = address +  "Store timings - 7 days: 11AM to 8PM  (7 days)<br>"
5793 rajveer 2935
    return address
2936
 
7428 rajveer 2937
def __get_hotspot_store_address_html(store):
7454 rajveer 2938
    address = store.line1 + ", "
7428 rajveer 2939
    if store.line2:
7430 rajveer 2940
        address = address + store.line2 + ", "
2941
    address = address + store.city + ", "
2942
    address = address + store.state + ", "
2943
    address = address + "PIN - " + store.pin
7428 rajveer 2944
    return address
2945
 
4815 phani.kuma 2946
def __generate_return_advice(order, warehouse, provider, filename):
2947
    if warehouse.id == 7:
7181 rajveer 2948
        executive = 'Shiv Kumar'
4815 phani.kuma 2949
    else:
4966 phani.kuma 2950
        executive = 'Dinesh Kumar'
2536 chandransh 2951
    pdf = Canvas(filename)
2952
    pdf.setFont('Times-Bold',16)
2953
    address_text = pdf.beginText(inch, PAGE_HEIGHT - inch)
2954
    address_text.textLine("To")
4815 phani.kuma 2955
    address_text.textLine(executive)
2536 chandransh 2956
    for line in warehouse.location.split("\n"):
2957
        address_text.textLine(line)
2958
    address_text.textLine("PIN " + warehouse.pincode)
2959
    pdf.drawText(address_text)
2960
 
2961
    pdf.setFont('Times-Roman',12)
2962
    order_text = pdf.beginText(inch, PAGE_HEIGHT - 4 * inch)
7792 anupam.sin 2963
    for detail in provider.details:
7801 anupam.sin 2964
        if detail.deliveryType == DeliveryType.PREPAID and detail.logisticLocation == warehouse.logisticsLocation :
7792 anupam.sin 2965
            order_text.textLine("Pickup CODE: " + detail.accountNo)
2536 chandransh 2966
    lineitem = order.lineitems[0] 
4234 rajveer 2967
    order_text.textLine("Content : " + lineitem.brand + " " + str(lineitem.model_number) + " " + str(lineitem.color))
2536 chandransh 2968
    order_text.textLine("Declared Value: Rs. " + str(order.total_amount))
2969
    order_text.textLine("Order ID : " + str(order.id))
2970
    pdf.drawText(order_text)
2971
    pdf.showPage()
2972
    pdf.save()
2973
    return filename
2974
 
7423 anupam.sin 2975
def __push_store_collection_to_hotspot(order, ctype, cashamount, cardamount):
7406 rajveer 2976
    ts = datetime.datetime.now()
2977
    store =  get_hotspot_store(order.storeId, "")
2978
 
2979
    soc = StoreOrderCollection()
2980
    soc.hotspotId = store.hotspotId
2981
    soc.orderId = order.id
2982
    soc.collectionType = ctype
7423 anupam.sin 2983
    soc.advanceAmount = int(cashamount + cardamount)
7406 rajveer 2984
    soc.productName =  str(order.lineitems[0]) 
2985
    soc.addedAt = ts
2986
    soc.pushedToOcr = False
7423 anupam.sin 2987
    soc.cash = int(cashamount)
2988
    soc.card = int(cardamount)
7406 rajveer 2989
    session.commit()
2990
 
7385 rajveer 2991
    try:
7406 rajveer 2992
        rcs = StoreOrderCollection.query.filter(StoreOrderCollection.pushedToOcr == False).all()
2993
        for cs in rcs:
2994
            store_string = "<Store>" + cs.hotspotId + "</Store>"
2995
            order_string = "<OrderID>" + str(cs.orderId) + "</OrderID>"
2996
            product_string = "<Product>" + cs.productName + "</Product>"
2997
            collection_type = "<CollectionType>" + cs.collectionType + "</CollectionType>"
2998
            amount_string = "<AdvanceAmount>" + str(cs.advanceAmount) + "</AdvanceAmount>"
2999
            date_string = "<Date>" + cs.addedAt.strftime("%Y%m%d") + "</Date>"
3000
            time_string = "<Time>" + cs.addedAt.strftime("%H%M%S") + "</Time>"
3001
            cash_string = "<CashAmount>" + str(cs.cash) + "</CashAmount>"
3002
            card_string = "<CardAmount>" + str(cs.card) + "</CardAmount>"
3003
 
3004
            #advance, saleClosure, advanceRefund, cashRefund, cardRefund
3005
 
3006
            conn = httplib.HTTPConnection("182.71.104.186")
3007
            XML="""
3008
            <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3009
              <soap:Body>
3010
                <SaholicAdvanceTransfer xmlns="http://tempuri.org/">
3011
            """
3012
 
3013
            XML = XML + store_string + order_string + product_string + collection_type + amount_string + cash_string + card_string + time_string + date_string 
3014
 
3015
            footer = """
3016
                </SaholicAdvanceTransfer>
3017
              </soap:Body>
3018
            </soap:Envelope>
3019
            """
3020
            XML = XML + footer
3021
 
3022
            params = urllib.urlencode({'op': 'SaholicAdvanceTransfer'})
3023
            headers = { "Content-type": "text/xml", "Content-Length": "%d" % len(XML)}
3024
            conn.request("POST", "/loaddetect/Service.asmx?"+params, "", headers)
3025
            conn.send(XML)
3026
            response = conn.getresponse()
3027
            print response.status, response.reason
3028
            resp = response.read()
3029
            conn.close()
3030
            print resp
3031
            if "Saved Successfully" in resp:
3032
                cs.pushedToOcr = True
3033
                cs.pushedAt = datetime.datetime.now()
3034
                session.commit()
3035
            elif "Error in Saving Data" in resp:
3036
                mail_html("cnc.center@shop2020.in", "5h0p2o2o", ["rajveer.singh@shop2020.in", "anupam.singh@shop2020.in", "rajneesh.arora@shop2020.in"], "Problem while pushing store collection to OCR", resp, [])
3037
            else: 
3038
                mail_html("cnc.center@shop2020.in", "5h0p2o2o", ["rajveer.singh@shop2020.in", "anupam.singh@shop2020.in", "rajneesh.arora@shop2020.in"], "Problem while pushing store collection to OCR", resp, [])
3039
    except:
3040
        print "Problem while pushing to ocr"
7385 rajveer 3041
 
7344 rajveer 3042
def __push_collection_to_hotspot(order, type, storeOrder = False):
5806 rajveer 3043
    try:
7344 rajveer 3044
        storeName = '109'
3045
        if storeOrder:
3046
            store =  get_hotspot_store(order.storeId, "")
3047
            storeName = store.hotspotId
3048
            storeName = '109'
3049
        else:
3050
            logistics_client = LogisticsClient().get_client()
3051
            store = logistics_client.getPickupStore(order.pickupStoreId)
3052
            storeName = store.hotspotId
3053
        store_string = "<store>" + storeName + "</store>"
5806 rajveer 3054
        order_string = "<orderno>" + str(order.id) + "</orderno>"
3055
        collection_type = "<Type>" + type + "</Type>"
5833 rajveer 3056
        payment_mode = get_order_attribute_value(order.id, "PAYMENT_MODE")
5806 rajveer 3057
        if type == "SALE":
7344 rajveer 3058
            if storeOrder:
7350 rajveer 3059
                amount = int(order.advanceAmount)
3060
                ts = order.created_timestamp
7344 rajveer 3061
            else:
3062
                amount = int(order.total_amount-order.gvAmount)
7350 rajveer 3063
                ts = order.delivery_timestamp
5806 rajveer 3064
        if type == "SALE RETURN":
7344 rajveer 3065
            if storeOrder:
7350 rajveer 3066
                amount = -int(order.advanceAmount)
7344 rajveer 3067
            else:
3068
                amount = -int(order.total_amount-order.gvAmount)
5806 rajveer 3069
            ts = order.refund_timestamp
3070
        if payment_mode == "Cash":
3071
            cash_string = "<cash>" + str(amount) + "</cash>"
3072
            card_string = "<hdfc>0</hdfc>"
3073
        if payment_mode == "Card":
3074
            cash_string = "<cash>0</cash>"
3075
            card_string = "<hdfc>" + str(amount) + "</hdfc>"
3076
        date_string = "<date>" + ts.strftime("%Y%m%d") + "</date>"
3077
        time_string = "<time>" + ts.strftime("%H%M%S") + "</time>"
3078
 
7254 rajveer 3079
        conn = httplib.HTTPConnection("182.71.104.186")
5806 rajveer 3080
        XML="""
3081
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3082
          <soap:Body>
3083
            <SaholicDataTransfer xmlns="http://tempuri.org/">
3084
        """
3085
 
3086
        XML = XML + store_string + order_string + collection_type + cash_string + card_string + date_string + time_string 
3087
 
3088
        footer = """
3089
            </SaholicDataTransfer>
3090
          </soap:Body>
3091
        </soap:Envelope>
3092
        """
3093
        XML = XML + footer
3094
 
3095
        params = urllib.urlencode({'op': 'SaholicDataTransfer'})
3096
        headers = { "Content-type": "text/xml", "Content-Length": "%d" % len(XML)}
3097
        conn.request("POST", "/loaddetect/Service.asmx?"+params, "", headers)
3098
        conn.send(XML)
3099
        response = conn.getresponse()
3100
        print response.status, response.reason
3101
        resp = response.read()
3102
        conn.close()
3103
        print resp
3104
        if "Saved Successfully" in resp:
3105
            return True
3106
        elif "Error in Saving Data" in resp:
3107
            return False
3108
        else: 
3109
            return False
3110
    except Exception as e:
3111
        print e
3112
        return False
3113
 
2697 chandransh 3114
def get_return_orders(warehouse_id, from_date, to_date):
3115
    query = ReturnOrder.query.filter_by(processedStatus = False)
3116
    if warehouse_id != -1:
3117
        query = query.filter_by(warehouseId = warehouse_id)
3118
    if from_date:
4118 chandransh 3119
        query = query.filter(ReturnOrder.createdAt >from_date)
2697 chandransh 3120
    if to_date:
4118 chandransh 3121
        query = query.filter(ReturnOrder.createdAt < to_date)
2697 chandransh 3122
    return [return_order.to_thrift_object() for return_order in query.all()]
3123
 
5481 phani.kuma 3124
def get_all_return_orders(onlyNotProcessed, from_date, to_date):
3125
    query = ReturnOrder.query
3126
    if onlyNotProcessed:
3127
        query = query.filter_by(processedStatus = False)
3128
    if from_date:
3129
        query = query.filter(ReturnOrder.createdAt >= from_date)
3130
    if to_date:
3131
        query = query.filter(ReturnOrder.createdAt <= to_date)
3132
    return [return_order.to_thrift_object() for return_order in query.all()]
3133
 
2700 chandransh 3134
def get_return_order(id):
3135
    ret_order = ReturnOrder.get_by(orderId = id)
3136
    if ret_order is None:
3137
        raise TransactionServiceException(116, "No return order found for the given order id")
3138
    return ret_order.to_thrift_object()
3139
 
2697 chandransh 3140
def process_return(ret_order_id):
3141
    ret_order = ReturnOrder.get_by(orderId = ret_order_id)
3142
    if ret_order is None:
3143
        raise TransactionServiceException(116, "No return order found for the given order id")
3144
    ret_order.processedStatus = True
2701 chandransh 3145
    ret_order.processedAt = datetime.datetime.now()
2697 chandransh 3146
    session.commit()
3147
 
4757 mandeep.dh 3148
def update_orders_as_PORaised(itemIdQuantityMap, purchaseOrderId, warehouseId):
3149
    """
3150
    Updates orders as PO raised. Also updates purchase order id in orders. Pass a map of items mapped to
3151
    the quantities for which the PO is raised.
3152
 
3153
    Parameters:
3154
     - itemIdQuantityMap
3155
     - purchaseOrderId
3156
     - warehouseId
3157
    """
3451 chandransh 3158
    query = Order.query.with_lockmode("update").filter_by(warehouse_id=warehouseId)
4757 mandeep.dh 3159
    query = query.filter(or_(Order.status == OrderStatus.SUBMITTED_FOR_PROCESSING, Order.status == OrderStatus.INVENTORY_LOW))
2819 chandransh 3160
    query = query.filter_by(purchase_order_id=None)
3161
    query = query.order_by(Order.created_timestamp)
3162
    pending_orders = query.all()
4586 mandeep.dh 3163
 
3164
    for order in pending_orders:
4757 mandeep.dh 3165
        lineitem = order.lineitems[0]
3166
        if itemIdQuantityMap.has_key(lineitem.item_id):
3167
            if itemIdQuantityMap[lineitem.item_id] >= lineitem.quantity:
3168
                order.status = OrderStatus.LOW_INV_PO_RAISED
3169
                order.statusDescription = 'In Process'
3170
                order.purchase_order_id = purchaseOrderId
3171
                itemIdQuantityMap[lineitem.item_id] -= lineitem.quantity
4434 mandeep.dh 3172
 
2819 chandransh 3173
    session.commit()
3174
 
3451 chandransh 3175
def update_weight(order_id, weight):
3469 chandransh 3176
    '''
3177
    Update the weight of order
3178
    '''
3451 chandransh 3179
    order = get_order(order_id)
3180
    order.total_weight = weight
3469 chandransh 3181
    lineitem = order.lineitems[0]
3182
    lineitem.total_weight = weight
3183
    lineitem.unit_weight = weight
3451 chandransh 3184
 
3469 chandransh 3185
    session.commit()
3186
    return order
3187
 
7560 rajveer 3188
def change_courier_provider(order_id, provider_id):
3189
    order = get_order(order_id)
7564 rajveer 3190
    if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED, OrderStatus.BILLED]:
7560 rajveer 3191
        raise TransactionServiceException(121, "This order has already been processed. Please seek help from engineering.")
3192
 
3193
    if order.logistics_provider_id == provider_id:
3194
        raise TransactionServiceException(121, "Provider Id entered by you is same as provider assigned to order.")
3195
 
3196
    logistics_client = LogisticsClient().get_client()
3197
    awb_number = logistics_client.getEmptyAWB(provider_id, order.cod)
3198
    order.logistics_provider_id = provider_id
3199
    order.airwaybill_no = awb_number
3200
    order.track_id = awb_number
3201
    session.commit()
3202
 
3203
    return order
3204
 
3469 chandransh 3205
def change_product(order_id, item_id):
3206
    '''
3207
    Ship a product of a different color to the customer.
3208
    '''
3209
    order = get_order(order_id)
4662 rajveer 3210
    if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT]:
3469 chandransh 3211
        raise TransactionServiceException(120, "This order has already been processed. Please seek help from engineering.")
3212
 
3213
    lineitem = order.lineitems[0]
3451 chandransh 3214
 
3469 chandransh 3215
    catalog_client = CatalogClient().get_client()
3216
 
3217
    old_item = catalog_client.getItem(lineitem.item_id)
3218
    item = catalog_client.getItem(item_id)
3219
    if old_item.catalogItemId != item.catalogItemId:
3220
        raise TransactionServiceException(121, "You can't ship a different item. You can only ship the same item in a different color.")
3221
 
5944 mandeep.dh 3222
    inventoryClient = InventoryClient().get_client()
5966 rajveer 3223
    inventoryClient.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
5110 mandeep.dh 3224
    __update_inventory_reservation(order)
3469 chandransh 3225
    #TODO: Check that this new item has the same price
3226
 
3227
    lineitem.item_id = item_id
3228
    lineitem.color = item.color
3229
 
3451 chandransh 3230
    session.commit()
3469 chandransh 3231
 
3232
    order = get_order(order_id)
3451 chandransh 3233
    return order
3469 chandransh 3234
 
3235
def change_warehouse(order_id, warehouse_id):
3236
    '''
3237
    Update the warehouse which will be used to fulfil this order.
3238
    '''
3239
    order = get_order(order_id)
6019 rajveer 3240
    if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3469 chandransh 3241
        raise TransactionServiceException(117, "This order has already been processed. Please seek help from engineering.")
3242
 
3243
    if warehouse_id == order.warehouse_id:
3244
        raise TransactionServiceException(118, "You have selected the current warehouse again. Nothing to do")
3245
 
3246
    lineitem = order.lineitems[0]
3247
    catalog_client = CatalogClient().get_client()
5944 mandeep.dh 3248
    inventoryClient = InventoryClient().get_client()
3469 chandransh 3249
    try:
5944 mandeep.dh 3250
        warehouse = inventoryClient.getWarehouse(warehouse_id)
3469 chandransh 3251
    except:
3252
        raise TransactionServiceException(119, "No warehouse with id" + str(warehouse_id))
5110 mandeep.dh 3253
 
6870 rajveer 3254
    if not warehouse.billingWarehouseId:
5147 mandeep.dh 3255
        raise TransactionServiceException(119, "Shifting of warehouse allowed to warehouse with billing support only")
5110 mandeep.dh 3256
 
5620 mandeep.dh 3257
    # If One gives a billing warehouse for warehouse shift, we should assign order to the GOOD warehouse
3258
    # present within it with maximum availability
3259
    if warehouse.id == warehouse.billingWarehouseId:
5944 mandeep.dh 3260
        warehouses = inventoryClient.getWarehouses(None, InventoryType.GOOD, 0, 0, warehouse.id)
5147 mandeep.dh 3261
        if warehouses:
5944 mandeep.dh 3262
            itemInventory = inventoryClient.getItemInventoryByItemId(lineitem.item_id)
5147 mandeep.dh 3263
            warehouse = warehouses[0]
3264
            maxAvailability = 0
3265
            for goodWarehouse in warehouses:
3266
                if itemInventory.availability.has_key(goodWarehouse.id) and maxAvailability < itemInventory.availability[goodWarehouse.id]:
3267
                    warehouse = goodWarehouse
3268
                    maxAvailability = itemInventory.availability[goodWarehouse.id]
3269
 
3270
            # Use preferred vendor's warehouse if not available anywhere
3271
            if not maxAvailability:
3272
                item = catalog_client.getItem(lineitem.item_id)
3273
                if item.preferredVendor:
3274
                    for goodWarehouse in warehouses:
3275
                        if goodWarehouse.vendor.id == item.preferredVendor:
3276
                            warehouse = goodWarehouse
3277
        else:
3278
            raise TransactionServiceException(119, "Shifting of warehouse allowed to GOOD inventory type warehouse with billing support")
3279
 
6007 rajveer 3280
    inventoryClient.reserveItemInWarehouse(lineitem.item_id, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5110 mandeep.dh 3281
    __update_inventory_reservation(order)
6789 rajveer 3282
    if order.status == OrderStatus.ACCEPTED:
3283
        __update_transfer_price(order, warehouse.id)
5110 mandeep.dh 3284
    order.warehouse_id = warehouse.billingWarehouseId
5147 mandeep.dh 3285
    order.fulfilmentWarehouseId = warehouse.id
3469 chandransh 3286
    session.commit()
3287
    return order
3553 chandransh 3288
 
6789 rajveer 3289
def __update_transfer_price(order, warehouse_id):
3290
    lineitem = order.lineitems[0]
3291
    inventory_client = InventoryClient().get_client()
3292
    warehouse = inventory_client.getWarehouse(warehouse_id)
3293
    item_pricing = inventory_client.getItemPricing(lineitem.item_id, warehouse.vendor.id)
3294
    lineitem.transfer_price = item_pricing.transferPrice
3295
    lineitem.nlc = item_pricing.nlc
3296
 
4647 rajveer 3297
def add_delay_reason(order_id, reason, further_delay, delayReasonText):
3553 chandransh 3298
    '''
3994 chandransh 3299
    Adds a delay reason to the order and updates the expected delivery time.
3553 chandransh 3300
    '''
3301
    order = get_order(order_id)
3302
    try:
3581 chandransh 3303
        order.delay_reason = DelayReason._VALUES_TO_NAMES[reason]
4647 rajveer 3304
        order.delayReasonText = delayReasonText
4009 chandransh 3305
        actual_delivery_delay = adjust_delivery_time(order.expected_delivery_time, further_delay)
3306
        order.expected_delivery_time = order.expected_delivery_time + datetime.timedelta(days=actual_delivery_delay)
4102 chandransh 3307
 
4842 rajveer 3308
        actual_shipping_delay = adjust_delivery_time(order.expected_shipping_time, further_delay)
3309
        order.expected_shipping_time = order.expected_shipping_time + datetime.timedelta(days=actual_shipping_delay)
4102 chandransh 3310
 
6726 rajveer 3311
        order.courier_delivery_time = order.courier_delivery_time + datetime.timedelta(days=adjust_delivery_time(order.courier_delivery_time, further_delay))
3312
 
3553 chandransh 3313
        session.commit()
4008 mandeep.dh 3314
 
3315
        try:
3316
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
3317
            transaction_requiring_extra_processing.category = 'DELAYED_DELIVERY'
3318
            transaction_requiring_extra_processing.transaction_id = order.transaction_id
3319
            session.commit()
3320
        except Exception as e:
4065 mandeep.dh 3321
            print 'Could not persist transaction id: ' + str(order.transaction_id) + ' for further processing due to: ' + str(e)
4008 mandeep.dh 3322
 
3553 chandransh 3323
        return True
3324
    except:
3994 chandransh 3325
        print sys.exc_info()[0]
3553 chandransh 3326
        return False
3956 chandransh 3327
 
3328
def reconcile_cod_collection(collected_amount_map, xferBy, xferTxnId, xferDate):
3329
    unprocessed_awbs = {}
3330
    for awb, amount in collected_amount_map.iteritems():
3331
        try:
3332
            order = Order.query.filter_by(airwaybill_no=awb).one()
3333
        except NoResultFound:
3334
            unprocessed_awbs[awb] = "No order was found for the given AWB: " + awb
3335
            continue
3336
        except MultipleResultsFound:
3337
            unprocessed_awbs[awb] = "Multiple orders were found for the given AWB:" + awb
3338
            continue
3339
 
3340
        if order.cod_reconciliation_timestamp:
3341
            #This order has been processed already! This may be a re-run. Let's allow other orders to be processed.
3342
            continue
3343
 
3344
        if order.status < OrderStatus.DELIVERY_SUCCESS:
3345
            #Order has not been delivered yet. No way we can receive the payment.
3346
            unprocessed_awbs[awb] = "Payment has been received for order: " + str(order.id) + " before delivery reconciliation"
3347
            continue
3348
 
4252 rajveer 3349
        ##As per ticket #743 if amount difference less than 0.5 we should reconcile
6318 rajveer 3350
        if abs(amount - (order.total_amount - order.gvAmount)) > 0.5:
3956 chandransh 3351
            #Received amount is less than or more than the order amount. Mustn't let the user proceed.
6318 rajveer 3352
            unprocessed_awbs[awb] = "Payment of Rs. " + str(amount) + " has been received against the total value of Rs. " + str(order.total_amount-order.gvAmount) + " for order: " + str(order.id)
3956 chandransh 3353
            continue
3354
 
3355
        try:
3356
            payment_client = PaymentClient().get_client()
3357
            payment_client.partiallyCapturePayment(order.transaction.id, amount, xferBy, xferTxnId, xferDate)
3358
        except Exception:
3359
            unprocessed_awbs[awb] = "We were unable to partially capture payment for order id " + str(order.id) + ", AWB: " + awb
3360
            continue
3361
 
3362
        #Payment has been recorded now. We can update the order peacefully.
3363
        order.cod_reconciliation_timestamp = datetime.datetime.now()
3364
        session.commit()
3469 chandransh 3365
 
3956 chandransh 3366
    return unprocessed_awbs
4008 mandeep.dh 3367
 
3368
def get_transactions_requiring_extra_processing(category):
4065 mandeep.dh 3369
    """
3370
    Returns the list of transaction ids that require some extra processing and
3371
    which belong to a particular category. This is currently used by CRM
3372
    application. If no such transaction ids are present, it returns an empty list.
3373
    """
3374
    query = TransactionRequiringExtraProcessing.query
4008 mandeep.dh 3375
 
4065 mandeep.dh 3376
    if category is not None:
3377
        query = query.filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category))
4008 mandeep.dh 3378
 
4065 mandeep.dh 3379
    return [a.transaction_id for a in query.all()]
4008 mandeep.dh 3380
 
3381
def mark_transaction_as_processed(transactionId, category):
4065 mandeep.dh 3382
    """
3383
    Marks a particular transaction as processed for a particular cateogory.
3384
    It essentially deletes the transaction id record for a particular
3385
    processing type category (if present) from DB.
3386
    This is currently used by CRM application.
3387
    """
4008 mandeep.dh 3388
    TransactionRequiringExtraProcessing.query.filter_by(transaction_id = transactionId).filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category)).delete()
3389
    session.commit()
3390
 
4018 chandransh 3391
def get_item_wise_risky_orders_count():
3392
    """
3393
    Returns a map containing the number of risky orders keyed by item id. A risky order
3394
    is defined as one whose shipping date is about to expire.
3395
    """
3396
    item_wise_risky_orders_count = {}
4019 chandransh 3397
    shipping_cutoff_time = (datetime.datetime.now() + datetime.timedelta(days = 1)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4018 chandransh 3398
    orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED]))).filter(Order.expected_shipping_time <= shipping_cutoff_time).all()
3399
    for order in orders:
3400
        for lineitem in order.lineitems:
3401
            quantity = lineitem.quantity
3402
            if item_wise_risky_orders_count.has_key(lineitem.item_id):
3403
                quantity = quantity + item_wise_risky_orders_count[lineitem.item_id]
3404
 
3405
            item_wise_risky_orders_count[lineitem.item_id] = quantity
3406
    return item_wise_risky_orders_count
3407
 
4324 mandeep.dh 3408
def update_shipment_address(order_id, address_id):
3409
    """
3410
    Updates shipment address of an order. Delivery and shipping date estimates
3411
    etc. are also updated here.
3412
 
3413
    Throws TransactionServiceException in case address change is not
3414
    possible due to certain reasons such as new pincode in address is
3415
    not serviceable etc.
3416
 
3417
    Parameters:
3418
     - orderId
3419
     - addressId
3420
    """
3421
    user_client = UserClient().get_client()
3422
    address     = user_client.getAddressById(address_id)
3423
    order       = get_order(order_id)
3424
 
4630 mandeep.dh 3425
    type = DeliveryType.PREPAID
3426
    if order.cod:
3427
        type = DeliveryType.COD
3428
 
4324 mandeep.dh 3429
    logistics_client = LogisticsClient().get_client()
5886 mandeep.dh 3430
    logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, address.pin, type)
4324 mandeep.dh 3431
 
3432
    # Check for new estimate. Raise exception if new address is not serviceable
3433
    if logistics_info.deliveryTime == -1:
3434
        raise TransactionServiceException(1, 'Location not serviceable')
3435
 
3436
    # COD services are not available everywhere
3437
    if order.cod:
4868 rajveer 3438
        if not logistics_info.codAllowed:
4324 mandeep.dh 3439
            raise TransactionServiceException(2, 'COD service not available')
3440
 
5593 mandeep.dh 3441
    if logistics_info.providerId != order.logistics_provider_id:
5887 mandeep.dh 3442
        logistics_info = logistics_client.getLogisticsInfo(address.pin, order.lineitems[0].item_id, type, PickUpType.COURIER)
5593 mandeep.dh 3443
        order.tracking_id = logistics_info.airway_billno
3444
        order.airwaybill_no = logistics_info.airway_billno
3445
        order.logistics_provider_id = logistics_info.providerId
3446
 
6525 rajveer 3447
    order.otg = logistics_info.otgAvailable
4324 mandeep.dh 3448
    current_time = datetime.datetime.now()
3449
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
3450
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 3451
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
4324 mandeep.dh 3452
 
3453
    order.customer_name         = address.name
3454
    order.customer_pincode      = address.pin
3455
    order.customer_address1     = address.line1
3456
    order.customer_address2     = address.line2
3457
    order.customer_city         = address.city
3458
    order.customer_state        = address.state
3459
    order.customer_mobilenumber = address.phone
3460
 
3461
    if order.cod:
3462
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3463
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3464
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3465
    else:
3466
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3467
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3468
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3469
 
3470
    order.promised_shipping_time = order.expected_shipping_time
3471
    order.promised_delivery_time = order.expected_delivery_time 
3472
 
3473
    session.commit()
3474
 
7730 anupam.sin 3475
def convert_store_to_normal(orderId):
3476
    """
3477
    This method is used to convert a pickup in store order into a normal one.
3478
    """
3479
    order = get_order(orderId)
3480
 
3481
    deliveryType = DeliveryType.PREPAID
3482
    if order.cod:
3483
        deliveryType = DeliveryType.COD
3484
 
3485
 
3486
    logistics_client = LogisticsClient().get_client()
3487
    logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, order.customer_pincode, deliveryType)
7792 anupam.sin 3488
    print "******"
3489
    print "got provider : " + str(logistics_info.providerId)
3490
    print "order provider : " + str(order.logistics_provider_id)
3491
    print "delivery time : " + str(logistics_info.deliveryTime)
3492
    print "codAllowed : " + str(logistics_info.codAllowed)
3493
    print "******"
7730 anupam.sin 3494
 
3495
    # Check for new estimate. Raise exception if new address is not serviceable
3496
    if logistics_info.deliveryTime == -1:
3497
        raise TransactionServiceException(1, 'Location not serviceable')
3498
 
3499
    # COD services are not available everywhere
3500
    if order.cod:
3501
        if not logistics_info.codAllowed:
3502
            raise TransactionServiceException(2, 'COD service not available')
3503
 
3504
    if logistics_info.providerId != order.logistics_provider_id:
7739 anupam.sin 3505
        logistics_info.airway_billno = logistics_client.getEmptyAWB(logistics_info.providerId, deliveryType)
7730 anupam.sin 3506
        order.tracking_id = logistics_info.airway_billno
3507
        order.airwaybill_no = logistics_info.airway_billno
3508
        order.logistics_provider_id = logistics_info.providerId
3509
        current_time = datetime.datetime.now()
3510
        logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
3511
        logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
3512
        logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
3513
 
3514
    order.pickupStoreId = 0
3515
    session.commit()
3516
    return True
3517
 
4247 rajveer 3518
def mark_order_cancellation_request_received(orderId):
3519
    """
3520
    Mark order as cancellation request received. If customer sends request of cancellation of
3521
    a particular order, this method will be called. It will just change status of the order
3522
    depending on its current status. It also records the previous status, so that we can move
3523
    back to that status if cancellation request is denied.
3524
 
3525
    Parameters:
3526
     - orderId
3527
    """
4662 rajveer 3528
    status_transition = {OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3529
             OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCEL_REQUEST_RECEIVED,
3530
             OrderStatus.INVENTORY_LOW : OrderStatus.CANCEL_REQUEST_RECEIVED,
4306 rajveer 3531
             OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3532
             OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCEL_REQUEST_RECEIVED,
3533
             OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3534
             OrderStatus.ACCEPTED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3535
             OrderStatus.BILLED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3536
             OrderStatus.PAYMENT_FLAGGED : OrderStatus.CANCEL_REQUEST_RECEIVED
3537
             }
4662 rajveer 3538
 
3539
    order = get_order(orderId)
4247 rajveer 3540
    if order.status not in status_transition.keys():
3541
        raise TransactionServiceException(114, "This order can't be considered for cancellation")
3542
 
4662 rajveer 3543
 
4247 rajveer 3544
    order.previousStatus = order.status
3545
    order.status = OrderStatus.CANCEL_REQUEST_RECEIVED
3546
    order.statusDescription = "Cancellation request received from user"
3547
    session.commit()
3548
 
4662 rajveer 3549
def mark_order_as_lost_in_transit(orderId):
3550
    """
3551
    Parameters:
3552
     - orderId
3553
    """
3554
    order = get_order(orderId)
4910 phani.kuma 3555
    if order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
4662 rajveer 3556
        raise TransactionServiceException(115, "This order can't be marked as lost in transit")
3557
    order.status = OrderStatus.LOST_IN_TRANSIT
3558
    order.statusDescription = "Lost in Transit"
3559
    session.commit()
3560
 
4258 rajveer 3561
def mark_transaction_as_payment_flag_removed(transactionId):
4247 rajveer 3562
    """
4258 rajveer 3563
    If we and/or payment gateway has decided to accept the payment, this method needs to be called.
3564
    Changed transaction and all orders status to payment accepted.
4247 rajveer 3565
 
3566
    Parameters:
4258 rajveer 3567
     - transactionId
4247 rajveer 3568
    """
4258 rajveer 3569
    transaction = get_transaction(transactionId)
3570
    transaction.status = TransactionStatus.AUTHORIZED
3571
    for order in transaction.orders:
3572
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
3573
        order.statusDescription = "Submitted to warehouse"
4247 rajveer 3574
    session.commit()
3575
 
4259 anupam.sin 3576
def refund_transaction(transactionId, refundedBy, reason):
3577
    """
3578
    This method is called when a flagged payment is deemed unserviceable and the corresponding orders
3579
    need to be cancelled
3580
 
3581
    Parameters:
3582
     - transactionId
3583
    """
3584
    transaction = get_transaction(transactionId)
3585
    transaction.status = TransactionStatus.FAILED
3586
    for order in transaction.orders:
3587
        refund_order(order.id, refundedBy, reason)
3588
    session.commit()
3589
 
4247 rajveer 3590
def mark_order_cancellation_request_denied(orderId):
3591
    """
4283 anupam.sin 3592
    If we decide to not to cancel order, we will move the order to previous status.
4247 rajveer 3593
 
3594
    Parameters:
3595
     - orderId
3596
    """
3597
    order = get_order(orderId)
3598
    order.status = order.previousStatus
3599
    order.previousStatus = None
3600
    order.statusDescription = "Cancellation request denied"
3601
    session.commit()
3602
 
3603
def mark_order_cancellation_request_confirmed(orderId):
3604
    """
3605
    If we decide to to cancel order, CRM will call this method to move the status of order to
3606
    cancellation request confirmed. After this OM will be able to cancel the order.
3607
 
3608
    Parameters:
3609
     - orderId
3610
    """
3611
    order = get_order(orderId)
3612
    order.status = OrderStatus.CANCEL_REQUEST_CONFIRMED
3613
    order.statusDescription = "Cancellation request confirmed"
3614
    session.commit()
3615
 
4285 rajveer 3616
def accept_orders_for_item_id(itemId, inventory):
3617
    """
3618
    Marks the orders as ACCEPTED for the given itemId and inventory. It also updates the accepted timestamp. If the
3619
    given order is not a COD order, it also captures the payment if the same has not been captured.
3620
 
3621
    Parameters:
3622
     - itemId
3623
     - inventory
3624
    """
6782 rajveer 3625
    orders = Order.query.filter(Order.warehouse_id == 9).filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.expected_shipping_time).all()
4285 rajveer 3626
    for order in orders:
4301 rajveer 3627
        if inventory > 0:
3628
            lineitem = order.lineitems[0]
3629
            if itemId == lineitem.item_id:
3630
                try:
3631
                    accept_order(order.id)
3632
                    inventory = inventory - lineitem.quantity
3633
                except:
3634
                    logging.info("Unable to accept the order")
3635
        else:
3636
            order_outofstock(order.id)
4285 rajveer 3637
    return
3638
 
6864 rajveer 3639
def move_orders_to_correct_warehouse():
3640
    orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.promised_shipping_time).all()
3641
    logistics_client = LogisticsClient().get_client()
3642
    for order in orders:
3643
        lineitem = order.lineitems[0]
7566 rajveer 3644
        logistics_info = logistics_client.getLogisticsEstimation(lineitem.item_id, order.customer_pincode, order.cod)
6864 rajveer 3645
        if order.fulfilmentWarehouseId != logistics_info.fulfilmentWarehouseId:
6870 rajveer 3646
            try:
3647
                print "++++" + str(order.id) + "=" + str(order.fulfilmentWarehouseId) + "->"+ str(logistics_info.fulfilmentWarehouseId)
3648
                change_warehouse(order.id, logistics_info.fulfilmentWarehouseId)
3649
            except:
3650
                print "++++" + str(order.id)
6864 rajveer 3651
 
4607 rajveer 3652
def get_slipped_sipping_date_orders():
4662 rajveer 3653
    return Order.query.filter(Order.status.in_(tuple([OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.ACCEPTED, OrderStatus.BILLED]))).filter(Order.promised_shipping_time <= datetime.datetime.now()).order_by(Order.promised_shipping_time).all()
4709 rajveer 3654
 
3655
def get_cancelled_orders(cancelDateFrom, cancelDateTo):
3656
    return Order.query.filter(Order.status == OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY).filter(Order.refund_timestamp >= cancelDateFrom).filter(Order.refund_timestamp <= cancelDateTo).all()
4607 rajveer 3657
 
4369 rajveer 3658
def mark_orders_as_po_raised(vendorId, itemId, quantity, estimate, isReminder):
3659
    if isReminder:
3660
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3661
    else:
3662
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3663
 
3664
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3665
    for order in orders:
3666
        lineitem = order.lineitems[0]
3667
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3668
            if estimate > 0:
3669
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3670
            order.status = OrderStatus.LOW_INV_PO_RAISED
4362 rajveer 3671
            order.statusDescription = "PO Raised"
4303 rajveer 3672
            quantity = quantity - lineitem.quantity
3673
            store_inventory_action(order, itemId, HotspotAction.PO_RAISED, estimate, lineitem.quantity)
3674
            session.commit()
3675
 
4369 rajveer 3676
def mark_orders_as_reversal_initiated(vendorId, itemId, quantity, estimate, isReminder):
3677
    if isReminder:
3678
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3679
    else:
3680
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3681
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3682
    for order in orders:
3683
        lineitem = order.lineitems[0]
3684
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3685
            if estimate > 0:
3686
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3687
            order.status = OrderStatus.LOW_INV_REVERSAL_IN_PROCESS
4362 rajveer 3688
            order.statusDescription = "Reversal Initiated"
4303 rajveer 3689
            quantity = quantity - lineitem.quantity
3690
            store_inventory_action(order, itemId, HotspotAction.REVERSAL_INITIATED, estimate, lineitem.quantity)
3691
            session.commit()
3692
 
4369 rajveer 3693
def mark_orders_as_not_available(vendorId, itemId, quantity, estimate, isReminder):
3694
    if isReminder:
3695
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3696
    else:
3697
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3698
 
3699
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3700
    for order in orders:
3701
        lineitem = order.lineitems[0]
3702
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3703
            order.status = OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT
4362 rajveer 3704
            order.statusDescription = "Not Available"
4303 rajveer 3705
            quantity = quantity - lineitem.quantity
3706
            store_inventory_action(order, itemId, HotspotAction.NOT_AVAILABLE, estimate, lineitem.quantity)
3707
            session.commit()
3708
 
3709
def store_inventory_action(order, itemId, hotspotAction, estimate, quantity):
4369 rajveer 3710
    orderInv = OrderInventory.get_by(order_id=order.id)
3711
    if not orderInv:
3712
        orderInv = OrderInventory()
3713
        orderInv.order = order
4303 rajveer 3714
    orderInv.hotspotAction = hotspotAction  
3715
    orderInv.estimate = estimate
3716
    orderInv.itemId = itemId
3717
    orderInv.timestamp = datetime.datetime.now()
3718
    orderInv.quantity = quantity
3719
 
4556 mandeep.dh 3720
'''    
4369 rajveer 3721
def mark_orders_as_timeout(vendorId):
3722
    ret_timeouts = {}
3723
    orderInvs = OrderInventory.query.all()
3724
    for orderInv in orderInvs:
3725
        if orderInv.timestamp +  timedelta(days=orderInv.estimate) < datetime.datetime.now():
3726
            if not ret_timeouts.has_key(orderInv.itemId):
3727
                timeout = TimeoutSummary()
3728
                ret_timeouts[orderInv.itemId] = timeout
3729
            else:
3730
                timeout = ret_timeouts.get(orderInv.itemId)
3731
            if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3732
                if timeout.poRaised:
3733
                    timeout.poRaised += 1
3734
                else:
3735
                    timeout.poRaised = 1
3736
 
3737
                if timeout.poEstimate:
3738
                    timeout.poEstimate += orderInv.estimate
3739
                else:
3740
                    timeout.poEstimate = orderInv.estimate
3741
                orderInv.order.status = OrderStatus.LOW_INV_PO_RAISED_TIMEOUT
3742
                orderInv.order.statusDescription = "PO Raised Timeout"
3743
            elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3744
                if timeout.reversalInitiated:
3745
                    timeout.reversalInitiated += 1
3746
                else:
3747
                    timeout.reversalInitiated = 1
3748
 
3749
                if timeout.reversalEstimate:
3750
                    timeout.reversalEstimate += orderInv.estimate
3751
                else:
3752
                    timeout.reversalEstimate = orderInv.estimate
3753
                orderInv.order.status = OrderStatus.LOW_INV_REVERSAL_TIMEOUT
3754
                orderInv.order.statusDescription = "Reversal Initiated Timeout"
3755
            else:
3756
                orderInv.delete()
3757
    session.commit()
3758
    return ret_timeouts
4556 mandeep.dh 3759
'''
3760
 
3761
 
3762
def mark_orders_as_timeout(vendorId):
3763
    ret_timeouts = {}
3764
    orderInvs = OrderInventory.query.all()
3765
    for orderInv in orderInvs:
3766
        if not ret_timeouts.has_key(orderInv.itemId):
3767
            timeout = TimeoutSummary()
3768
            ret_timeouts[orderInv.itemId] = timeout
3769
        else:
3770
            timeout = ret_timeouts.get(orderInv.itemId)
3771
        if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3772
            if timeout.poRaised:
3773
                timeout.poRaised += 1
3774
            else:
3775
                timeout.poRaised = 1
3776
 
3777
            if timeout.poEstimate:
3778
                timeout.poEstimate = max(orderInv.estimate, timeout.poEstimate)
3779
            else:
3780
                timeout.poEstimate = orderInv.estimate
3781
        elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3782
            if timeout.reversalInitiated:
3783
                timeout.reversalInitiated += 1
3784
            else:
3785
                timeout.reversalInitiated = 1
3786
 
3787
            if timeout.reversalEstimate:
3788
                timeout.reversalEstimate = max(orderInv.estimate, timeout.reversalEstimate)
3789
            else:
3790
                timeout.reversalEstimate = orderInv.estimate
3791
        orderInv.order.status = OrderStatus.INVENTORY_LOW
3792
        orderInv.order.statusDescription = "Low Inventory"
3793
        orderInv.delete()
3794
    session.commit()
3795
    return ret_timeouts
3796
 
4386 anupam.sin 3797
def get_order_for_awb(awb):
3798
    order = Order.get_by(airwaybill_no=awb)
3799
    if not order:
3800
        raise TransactionServiceException(108, "no such order")
3801
 
3802
    return order
4369 rajveer 3803
 
4910 phani.kuma 3804
def get_orders_for_provider_for_status(provider_id, order_status_list):
3805
    if not provider_id or not order_status_list:
4506 phani.kuma 3806
        raise TransactionServiceException(101, "bad provider id or order status")
4910 phani.kuma 3807
    doa_provider = False
3808
    for order_status in order_status_list:
3809
        if order_status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_PICKUP_CONFIRMED]:
3810
            doa_provider = True
3811
    if doa_provider:
3812
        query = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4815 phani.kuma 3813
    else:
4910 phani.kuma 3814
        query = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4506 phani.kuma 3815
    return query.all()
4386 anupam.sin 3816
 
4600 varun.gupt 3817
def get_billed_orders_for_vendor(vendor_id, billing_date_from, billing_date_to):
5368 mandeep.dh 3818
    query = Order.query.filter(Order.status != OrderStatus.PAYMENT_PENDING)
3819
 
3820
    if vendor_id:
3821
        query = query.filter_by(vendorId = vendor_id)
3822
 
4600 varun.gupt 3823
    if billing_date_from:
3824
        query = query.filter(Order.billing_timestamp >= billing_date_from)
5368 mandeep.dh 3825
 
4600 varun.gupt 3826
    if billing_date_to:
3827
        query = query.filter(Order.billing_timestamp <= billing_date_to)
5368 mandeep.dh 3828
 
4600 varun.gupt 3829
    return query.all()
3830
 
5481 phani.kuma 3831
def get_billed_orders(vendor_id, onlyVendorNotPaid, billing_date_from, billing_date_to):
5386 phani.kuma 3832
    query = Order.query.filter(Order.billing_timestamp != None)
5481 phani.kuma 3833
 
3834
    if onlyVendorNotPaid:
5488 phani.kuma 3835
        query = query.filter_by(vendor_paid = False)
5481 phani.kuma 3836
 
5386 phani.kuma 3837
    if vendor_id != -1:
3838
        query = query.filter_by(vendorId = vendor_id)
3839
 
5481 phani.kuma 3840
    if billing_date_from:
3841
        query = query.filter(Order.billing_timestamp >= billing_date_from)
3842
 
3843
    if billing_date_to:
3844
        query = query.filter(Order.billing_timestamp <= billing_date_to)
3845
 
4885 varun.gupt 3846
    return query.all()
4875 varun.gupt 3847
 
4600 varun.gupt 3848
def save_bluedart_settlements(map_awb_and_amount):
3849
    payment_client = PaymentClient().get_client()
3850
 
3851
    for awb, amount in map_awb_and_amount.iteritems():
3852
        order = Order.get_by(airwaybill_no = awb)
3853
 
3854
        payment = payment_client.getSuccessfulPaymentForTxnId(order.transaction_id)
3855
        settlement = PaymentSettlement()
3856
        settlement.paymentId = payment.paymentId
3857
        settlement.paymentGatewayId = payment.gatewayId
3858
        settlement.netCollection = amount
3859
        session.commit()
3860
 
4905 varun.gupt 3861
def save_payment_settlements(settlementDate, paymentGatewayId, referenceId, serviceTax, otherCharges, netCollection):
5386 phani.kuma 3862
    originalOrderId = None
3863
    if paymentGatewayId == 4:
3864
        cod_order = Order.get_by(id = referenceId)
3865
        if cod_order.originalOrderId:
3866
            originalOrderId = cod_order.originalOrderId
3867
        else:
3868
            originalOrderId = referenceId
4600 varun.gupt 3869
    settlement = PaymentSettlement()
3870
    settlement.settlementDate = settlementDate
3871
    settlement.paymentGatewayId = paymentGatewayId
5386 phani.kuma 3872
    if originalOrderId is not None:
3873
        settlement.originalOrderId = originalOrderId
4905 varun.gupt 3874
    settlement.referenceId = referenceId
4600 varun.gupt 3875
    settlement.serviceTax = serviceTax
3876
    settlement.otherCharges = otherCharges
3877
    settlement.netCollection = netCollection
3878
    session.commit()
3879
 
5386 phani.kuma 3880
def get_settlement_for_Prepaid(reference_id, is_refund = False):
3881
    query = PaymentSettlement.query.filter_by(referenceId = reference_id).filter(PaymentSettlement.paymentGatewayId != 4)
4600 varun.gupt 3882
 
5189 varun.gupt 3883
    if is_refund:
3884
        query = query.filter(PaymentSettlement.netCollection < 0)
3885
    else:
3886
        query = query.filter(PaymentSettlement.netCollection > 0)
3887
 
5386 phani.kuma 3888
    return query.first()
3889
 
3890
def get_settlement_for_Cod(orderId, is_refund = False):
3891
    query = PaymentSettlement.query.filter_by(originalOrderId = orderId)
5382 varun.gupt 3892
 
5386 phani.kuma 3893
    if is_refund:
3894
        query = query.filter(PaymentSettlement.netCollection < 0)
3895
    else:
3896
        query = query.filter(PaymentSettlement.netCollection > 0)
3897
 
5189 varun.gupt 3898
    return query.first()
4600 varun.gupt 3899
 
3900
def save_ebs_settlement_summary(settlement_id, settlement_date, transaction_date_from, transaction_date_to, amount):
5551 phani.kuma 3901
    summary = EBSSettlementSummary.query.filter_by(settlementId = settlement_id).first()
5481 phani.kuma 3902
    if summary is None:
3903
        summary = EBSSettlementSummary()
3904
        summary.settlementId = settlement_id
3905
        summary.settlementDate = settlement_date
3906
        summary.transactionDateFrom = transaction_date_from
3907
        summary.transactionDateTo = transaction_date_to
3908
        summary.amount = amount
3909
        summary.detailsUploaded = False
3910
        session.commit()
4600 varun.gupt 3911
 
3912
def get_ebs_settlement_summaries():
3913
    summaries = EBSSettlementSummary.query.filter_by(detailsUploaded = False).order_by(EBSSettlementSummary.transactionDateFrom).all()
3914
    summary_map = {}
3915
 
3916
    for summary in summaries:
3917
        transactionDateFrom = str(summary.transactionDateFrom.year) + '-' + str(summary.transactionDateFrom.month) + '-' + str(summary.transactionDateFrom.day)
3918
        transactionDateTo = str(summary.transactionDateTo.year) + '-' + str(summary.transactionDateTo.month) + '-' + str(summary.transactionDateTo.day)
3919
 
3920
        summary_map[summary.settlementId] = "%s to %s" %(transactionDateFrom, transactionDateTo)
3921
 
3922
    return summary_map
3923
 
3924
def get_ebs_settlement_date(settlement_id):
3925
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3926
 
3927
    if summary:
3928
        return summary.settlementDate
3929
 
3930
def mark_ebs_settlement_uploaded(settlement_id):
3931
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3932
 
3933
    if summary:
3934
        summary.detailsUploaded = True
3935
        session.commit()
4715 varun.gupt 3936
 
3937
def get_settlements_by_date(settlement_date_from, settlement_date_to, is_refund):
3938
    query = PaymentSettlement.query
4600 varun.gupt 3939
 
4715 varun.gupt 3940
    if settlement_date_from:
3941
        query = query.filter(PaymentSettlement.settlementDate >= settlement_date_from)
3942
 
3943
    if settlement_date_to:
3944
        query = query.filter(PaymentSettlement.settlementDate <= settlement_date_to)
3945
 
4749 varun.gupt 3946
    if is_refund is True:
3947
        query = query.filter(PaymentSettlement.netCollection < 0.0)
3948
    else:
3949
        query = query.filter(PaymentSettlement.netCollection > 0.0)
4715 varun.gupt 3950
 
4749 varun.gupt 3951
    return query.all()
4715 varun.gupt 3952
 
3953
def get_reshipped_order_ids(order_ids):
3954
    reshipped_order_ids = []
3955
    return [order.new_order_id for order in Order.query.filter(Order.new_order_id.in_(order_ids)).all()]
3956
 
4749 varun.gupt 3957
def get_shipping_confirmation_email_body(order):
3958
 
3959
    html = """
3960
<html>
3961
<body>
3962
<div>
3963
    <p>Dear Customer,</p>
3964
    <p>
4885 varun.gupt 3965
        We are pleased to inform that we have shipped the order: $order_id for your product $product_name on $shipping_datetime. 
5139 varun.gupt 3966
        The shipment will be delivered to you via $courier_name Courier Service vide AWB# $awb.
7198 amar.kumar 3967
 
4749 varun.gupt 3968
    </p>
3969
    <p>
6655 rajveer 3970
        Expected delivery date for your order is $expected_delivery_date.
6675 rajveer 3971
        <br/>
3972
        $otg_text
7198 amar.kumar 3973
        $freebie_text
6675 rajveer 3974
        <br/> 
6716 rajveer 3975
        The product can be delivered to you between business hours of 10am to 6pm.
3976
        You can Check the current shipment updates for your product online at <a href="www.saholic.com/myaccount">Open Orders</a>.
4749 varun.gupt 3977
    </p>
3978
    <p>
5573 amit.gupta 3979
        For scheduling the delivery of your product at some specific timings, we recommend you to contact the helpline for $courier_name with your complete AWB#.
4749 varun.gupt 3980
    </p>
5139 varun.gupt 3981
    <p>$courier_name: $courier_phone</p>
4749 varun.gupt 3982
    <p>
3983
        Warm Regards,<br />
6029 rajveer 3984
        $source_name Team
4749 varun.gupt 3985
    </p>
4750 varun.gupt 3986
</div>
4749 varun.gupt 3987
</body>
3988
</html>
3989
    """
7760 rajveer 3990
    logistics_providers = {1: {'name': 'BlueDart', 'phone': '011-66111234'}, 6: {'name': 'RedExpress', 'phone': '8373915813'}, 3: {'name': 'Delhivery', 'phone' : '0124- 4212200'}}
5139 varun.gupt 3991
    provider_name = logistics_providers[order.logistics_provider_id]['name']
3992
    provider_phone = logistics_providers[order.logistics_provider_id]['phone']
3993
 
5868 rajveer 3994
    lclient = LogisticsClient().get_client()
3995
    logistics_info = lclient.getLogisticsEstimation(order.lineitems[0].item_id, order.customer_pincode, DeliveryType.PREPAID)
4749 varun.gupt 3996
    dt = datetime.datetime.strptime(str(order.shipping_timestamp), "%Y-%m-%d %H:%M:%S")
4885 varun.gupt 3997
    shipping_date = dt.strftime("%A, %d %B %Y %I:%M%p")
6712 rajveer 3998
    product = str(order.lineitems[0])
5868 rajveer 3999
    new_expected_delivery_timestamp = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime)))
6728 rajveer 4000
    new_courier_delivery_time = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime - logistics_info.deliveryDelay)))
6666 rajveer 4001
    #update new expected timestamp
4002
    if order.cod:
6705 amar.kumar 4003
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 4004
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 4005
    else:
6705 amar.kumar 4006
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 4007
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 4008
    order.expected_delivery_time = new_expected_delivery_timestamp
4009
    session.commit()
4010
 
4885 varun.gupt 4011
    new_expected_delivery_date = new_expected_delivery_timestamp.strftime("%A, %d %B %Y")
6655 rajveer 4012
    otg_text = ""
4013
    if order.otg:
6662 rajveer 4014
        promised_delivery_date = order.promised_delivery_time.strftime("%A, %d %B %Y")
6655 rajveer 4015
        if new_expected_delivery_timestamp > order.promised_delivery_time:
6712 rajveer 4016
            otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We apologize in advance for the expected delay from our initial promised delivery date of ' + promised_delivery_date + '. Your will receive a Gift Voucher Code at time of delivery based on the actual delay. You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.'
6655 rajveer 4017
        elif new_expected_delivery_timestamp < order.promised_delivery_time:
6662 rajveer 4018
            otg_text = 'We are happy to inform you that we expect to deliver your order before time. Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> Please note, compensation for delay (If Any) will be computed from the initial promised delivery date of ' + promised_delivery_date + '.'
6655 rajveer 4019
        else:            
6662 rajveer 4020
            otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We are committed to deliver your order by our initial promised delivery date of ' + promised_delivery_date + '.'
7190 amar.kumar 4021
 
4022
    freebie_text = "<br/>"
4023
    if order.freebieItemId:
4024
        catalog_client = CatalogClient().get_client()
4025
        item = catalog_client.getItem(order.freebieItemId)
7198 amar.kumar 4026
        freebie_text = freebie_text = "We have also shipped you " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised<br/>"
7190 amar.kumar 4027
    else:
4028
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
4029
        if freebie_orderId != "":
4030
            line_items = get_line_items_for_order(int(freebie_orderId))
7198 amar.kumar 4031
            freebie_order = get_order(int(freebie_orderId))
7720 amar.kumar 4032
            if order.cod:
4033
                freebie_text = freebie_text + "We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be shipped within 72 hours of delivery of your product<br/>"
4034
            else:
4035
                freebie_text = freebie_text + "We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>"
7198 amar.kumar 4036
        else:
4037
            freebie_text = ""
6655 rajveer 4038
 
7190 amar.kumar 4039
    info = dict(order_id = order.id, product_name = product, shipping_datetime = shipping_date, awb = order.airwaybill_no, expected_delivery_date = new_expected_delivery_date, courier_name = provider_name, courier_phone = provider_phone, source_name = source_name, otg_text = otg_text, freebie_text = freebie_text)
4885 varun.gupt 4040
    return Template(html).substitute(info)
4749 varun.gupt 4041
 
5832 rajveer 4042
def enqueue_shipping_confirmation_email(order):
4915 varun.gupt 4043
    # Calling helper service on production
4044
    helperClient = HelperClient(host_key = "helper_service_server_host_prod").get_client()
5832 rajveer 4045
    try:
4046
        emailSubject = 'Shipping Details for Order ID: ' + str(order.id)
4047
        emailBody = get_shipping_confirmation_email_body(order)
6906 rajveer 4048
        helperClient.saveUserEmailForSending([order.customer_email], None, emailSubject, emailBody, str(order.id), 'ShippingConfirmation', [], [])
6687 rajveer 4049
 
5832 rajveer 4050
    except Exception as e:
4051
        print e
5139 varun.gupt 4052
 
4915 varun.gupt 4053
def get_order_distribution_by_status(start_date, end_date):
5067 varun.gupt 4054
    query = session.query(Order.status, func.count(Order.id)).group_by(Order.status)
4055
    query = query.filter(Order.created_timestamp >= start_date)
4056
    query = query.filter(Order.created_timestamp <= end_date)
4057
    return query.all()
4915 varun.gupt 4058
 
5067 varun.gupt 4059
def get_order_ids_for_status(status, start_datetime, end_datetime):
4060
    query = Order.query.filter(Order.status == status)
4061
    query = query.filter(Order.created_timestamp >= start_datetime)
4062
    query = query.filter(Order.created_timestamp <= end_datetime)
4063
    return query.all()
4064
 
5099 varun.gupt 4065
def update_orders_as_paid_to_vendor(order_id):
5139 varun.gupt 4066
    paid_order = Order.get_by(id = order_id)
5099 varun.gupt 4067
 
5139 varun.gupt 4068
    if paid_order.originalOrderId is None:
4069
        paid_order.vendor_paid = True
5099 varun.gupt 4070
        session.commit()
5139 varun.gupt 4071
 
4072
        for order in Order.query.filter(Order.originalOrderId == order_id).all():
4073
            order.vendor_paid = True
4074
            session.commit()
4075
    else:
5208 varun.gupt 4076
        original_order_id = paid_order.originalOrderId
5139 varun.gupt 4077
 
5208 varun.gupt 4078
        for order in Order.query.filter(Order.originalOrderId == original_order_id).all():
5139 varun.gupt 4079
            order.vendor_paid = True
4080
            session.commit()
4081
 
4082
        original_order = Order.get_by(id = original_order_id)
4083
        if original_order:  original_order.vendor_paid = True
4084
        session.commit()
5348 anupam.sin 4085
 
4086
def update_COD_agent(agentEmailId, orderId):
4087
    order = Order.get_by(id=orderId)
4088
    if not order:
4089
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
4090
    agent = CodVerificationAgent()
4091
    agent.orderId = orderId
4092
    agent.verificationAgent = agentEmailId
4093
    session.commit()
4094
 
5099 varun.gupt 4095
 
5386 phani.kuma 4096
def update_order_only_as_paid_to_vendor(order_id):
4097
    paid_order = Order.get_by(id = order_id)
4098
    if paid_order is None:
4099
        raise TransactionServiceException(116, "No order found for the given order id")
4100
    paid_order.vendor_paid = True
4101
    session.commit()
4102
 
5208 varun.gupt 4103
def get_refunded_orders_marked_paid():
4104
    orderStatusGroup = OrderStatusGroups()
4105
    return Order.query.filter(Order.vendor_paid == 1).filter(Order.status.in_(orderStatusGroup.refundedOrders)).all()
4106
 
5447 anupam.sin 4107
def get_all_verification_agents(minOrderId, maxOrderId):
4108
    return CodVerificationAgent.query.filter(CodVerificationAgent.orderId >= minOrderId).filter(CodVerificationAgent.orderId <= maxOrderId).all()
4109
 
5527 anupam.sin 4110
def get_all_attributes_for_order_id(orderId):
4111
    return Attribute.query.filter(Attribute.orderId == orderId).all()
4112
 
4113
def set_order_attribute_for_transaction(transactionId, t_attribute):
4114
    for order in Order.query.filter_by(transaction_id = transactionId).all():
4115
        attribute = Attribute()
4116
        attribute.orderId = order.id
4117
        attribute.name = t_attribute.name
4118
        attribute.value = t_attribute.value
4119
        session.commit()
5593 mandeep.dh 4120
 
5558 mandeep.dh 4121
def accept_order_for_item(itemId, quantity, fulfilmentWarehouseId, billingWarehouseId):
5944 mandeep.dh 4122
    inventoryClient = InventoryClient().get_client()
4123
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5684 mandeep.dh 4124
    orders = Order.query.filter(Order.fulfilmentWarehouseId != fulfilmentWarehouseId).filter(Order.warehouse_id == billingWarehouseId).filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.expected_shipping_time).all()
5558 mandeep.dh 4125
    for order in orders:
5593 mandeep.dh 4126
        lineitem = order.lineitems[0]
5558 mandeep.dh 4127
        if lineitem.item_id == itemId and lineitem.quantity <= quantity:
5944 mandeep.dh 4128
            warehouse = inventoryClient.getWarehouse(order.fulfilmentWarehouseId)
5684 mandeep.dh 4129
            if not warehouse.billingWarehouseId and warehouse.warehouseType == WarehouseType.THIRD_PARTY:
4130
                if (inventory.availability[fulfilmentWarehouseId] >= inventory.reserved[fulfilmentWarehouseId] + lineitem.quantity) and inventory.availability[order.fulfilmentWarehouseId] < inventory.reserved[order.fulfilmentWarehouseId]:
5966 rajveer 4131
                    inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
4132
                    inventoryClient.reserveItemInWarehouse(itemId, fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5684 mandeep.dh 4133
                    order.fulfilmentWarehouseId = fulfilmentWarehouseId
5558 mandeep.dh 4134
                    quantity -= lineitem.quantity
5684 mandeep.dh 4135
                    session.commit()
5593 mandeep.dh 4136
                    if not quantity:
4137
                        break
5558 mandeep.dh 4138
 
6031 rajveer 4139
def get_recharge_order(rechargeOrderId):
6048 rajveer 4140
    return RechargeOrder.get_by(id = rechargeOrderId)
6031 rajveer 4141
 
4142
def get_recharge_orders(userId):
4143
    return RechargeOrder.query.filter_by(userId = userId).all()
4144
 
7760 rajveer 4145
def update_recharge_order_status(rechargeOrderId, rechargeOrderStatus):
6031 rajveer 4146
    recharge_order = get_recharge_order(rechargeOrderId)
4147
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_FAILED:
4148
        recharge_order.status = RechargeOrderStatus.PAYMENT_FAILED
4149
        session.commit()
4150
        return True
6214 rajveer 4151
 
4152
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED:
4153
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
7760 rajveer 4154
        recharge_order.responseTimestamp = datetime.datetime.now()
6214 rajveer 4155
        session.commit()
4156
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 4157
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6214 rajveer 4158
        enqueue_recharge_info_email(recharge_order)
4159
        return True
4160
 
4161
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4162
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
6553 rajveer 4163
        recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
6214 rajveer 4164
        session.commit()
6285 rajveer 4165
        gvs = allocate_gift_voucher(recharge_order)
4166
        enqueue_recharge_info_email(recharge_order, gvs)
6214 rajveer 4167
        return True
4168
 
6279 rajveer 4169
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
4170
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED
7760 rajveer 4171
        order.responseTimestamp = datetime.datetime.now()
6279 rajveer 4172
        session.commit()
4173
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 4174
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6279 rajveer 4175
        enqueue_recharge_info_email(recharge_order)
4176
        return True
4177
 
6031 rajveer 4178
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6285 rajveer 4179
        gvs = {}
6206 rajveer 4180
        recharge_order.status = RechargeOrderStatus.PAYMENT_SUCCESSFUL
4181
        session.commit()
6031 rajveer 4182
        if recharge_order.walletAmount > 0:
4183
            wallet = get_user_wallet(recharge_order.userId)
4184
            if wallet and wallet.amount >= recharge_order.walletAmount:
4185
                update_amount_in_wallet(recharge_order.userId, -recharge_order.walletAmount, recharge_order.id)
4186
            else:
6441 rajveer 4187
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6031 rajveer 4188
                raise TransactionServiceException(103, 'Wallet amount has already been used')
4189
 
6092 rajveer 4190
        try:
4191
            if activate_recharge_txn(recharge_order):
4192
                recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
4193
                session.commit()
6285 rajveer 4194
                gvs = allocate_gift_voucher(recharge_order)
6092 rajveer 4195
                return True
4196
            else:
4197
                update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 4198
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6092 rajveer 4199
                session.commit()
4200
                return False
4201
        except:
4202
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
4203
            transaction_requiring_extra_processing.category = 'RECHARGE_UNKNOWN'
4204
            transaction_requiring_extra_processing.transaction_id = recharge_order.transaction_id
6031 rajveer 4205
            session.commit()
4206
            return False
6102 rajveer 4207
        finally:
6285 rajveer 4208
            enqueue_recharge_info_email(recharge_order, gvs)
6102 rajveer 4209
 
6031 rajveer 4210
 
6285 rajveer 4211
def allocate_gift_voucher(recharge_order):            
4212
    totalAmount = recharge_order.totalAmount
4213
    gvs = {}
6438 rajveer 4214
    return gvs
6330 rajveer 4215
    if totalAmount >= 100:
4216
        totalAmount=500 if totalAmount >= 500 else totalAmount
6285 rajveer 4217
        try:
4218
            pc = PromotionClient().get_client()
6330 rajveer 4219
            enddate = datetime.datetime.now() + datetime.timedelta(days=45)
6285 rajveer 4220
            while totalAmount > 0:
6330 rajveer 4221
                gvAmount = totalAmount if totalAmount <= 250 else 250
6285 rajveer 4222
                totalAmount = totalAmount - gvAmount
6561 amit.gupta 4223
                gv = pc.createCoupon(26, to_java_date(enddate), recharge_order.userEmailId, gvAmount, False, 1, None)
6285 rajveer 4224
                gvs[gv] = gvAmount  
4225
        except:
4226
            print "Not able to create gift voucher for user " + recharge_order.userEmailId
4227
    return gvs     
4228
 
6048 rajveer 4229
def activate_recharge_txn(recharge_order):
4230
    if isinstance(recharge_order, MobileRechargeOrder):
4231
        rechargeType = 'MTP'
4232
        deviceNumber = recharge_order.mobileNumber
4233
        strProviderCode = get_provider_code(recharge_order.mobileOperatorId)
6161 rajveer 4234
        plan = recharge_order.rechargePlan
6048 rajveer 4235
    if isinstance(recharge_order, DTHRechargeOrder):
4236
        rechargeType = 'RCH'
4237
        deviceNumber = recharge_order.dthAccountNumber
4238
        strProviderCode = get_provider_code(recharge_order.dthOperatorId)
6161 rajveer 4239
        plan = ''
7369 rajveer 4240
    retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(recharge_order.id, rechargeType, strProviderCode, deviceNumber, recharge_order.totalAmount, plan)
6231 rajveer 4241
    recharge_order.spiceTID = spiceTID
4242
    recharge_order.responseTimestamp = datetime.datetime.now()
4243
    recharge_order.description = description
4244
    session.commit()
6092 rajveer 4245
    if retCode == '00' and retStatus == 'S':
4246
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
4247
        session.commit()
4248
        return True
6259 rajveer 4249
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
6231 rajveer 4250
        raise TransactionServiceException(111, "No response from operator within specified time")
6092 rajveer 4251
    else:
4252
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
6265 rajveer 4253
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
4254
            recharge_order.description = "Invalid Amount"
4255
        elif retCode in ('ECL', 'SVECL', 'SCL'):
4256
            recharge_order.description = "Customer Exceeded Daily Limit"
4257
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
6399 rajveer 4258
            recharge_order.description = "Invalid Device Number"
6092 rajveer 4259
        session.commit()
6048 rajveer 4260
        return False
6031 rajveer 4261
 
6092 rajveer 4262
 
6031 rajveer 4263
def get_user_wallet(userId):
4264
    wallet = UserWallet.get_by(userId = userId)
4265
    if not wallet:
4266
        wallet = UserWallet()
4267
        wallet.amount = 0
4268
        wallet.userId = userId
4269
    return wallet
4270
 
4271
def get_user_wallet_history(userId):
4272
    wallet = get_user_wallet(userId)
4273
    if wallet.id:
4274
        return UserWalletHistory.query.filter_by(wallet = wallet).all()
4275
    else:
4276
        return []
4277
 
6125 rajveer 4278
def get_provider(providerId):
4279
    return ServiceProvider.query.filter_by(id = providerId).one()
4280
 
6048 rajveer 4281
def get_provider_code(providerId):
4282
    return ServiceProvider.query.filter_by(id = providerId).one().code
6031 rajveer 4283
 
6310 anupam.sin 4284
def get_provider_by_code(providerCode):
4285
    return ServiceProvider.query.filter_by(code = providerCode).one()
6049 rajveer 4286
 
6206 rajveer 4287
def get_service_providers(recharge_type, only_active):
4288
    query = ServiceProvider.query.filter_by(type = recharge_type)
4289
    if only_active:
4290
        query = query.filter_by(status = only_active)
4291
    providers = query.all()
6048 rajveer 4292
    serviceProviders = {}
4293
    for provider in providers:
4294
        serviceProviders[provider.id] = provider.name
4295
    return serviceProviders
4296
 
6049 rajveer 4297
def get_service_provider_for_device(rechargeType, deviceNumber):
7792 anupam.sin 4298
    #FIXME : This method does not take care of MNP cases.
6049 rajveer 4299
    if rechargeType == RechargeType.MOBILE:
4300
        serviceType = 'MTP'
4301
    if rechargeType == RechargeType.DTH:
4302
        serviceType = 'RCH'
6048 rajveer 4303
 
6313 anupam.sin 4304
    provider = None
7120 rajveer 4305
    try:
4306
        series = OperatorSeries.get_by(series = int(deviceNumber))
4307
        if series:
7122 rajveer 4308
            providerId = series.operatorId
7120 rajveer 4309
            tc = TelecomCircle.get_by(id = series.circleId)
4310
            operatorCircle = tc.code
6092 rajveer 4311
        else:
7120 rajveer 4312
            l = len(deviceNumber)
4313
            if l < 10:
4314
                deviceNumber = deviceNumber + "0" * (10-l) 
4315
            providerCode, operatorCircle = RechargeService.checkServiceProviderApi(serviceType, deviceNumber)
4316
            if providerCode == 'SNS' or providerCode == '':
4317
                providerId = 0
4318
            else:
4319
                provider = get_provider_by_code(providerCode)
4320
                providerId = provider.id
6049 rajveer 4321
    except:
6092 rajveer 4322
        providerId = -1
6643 rajveer 4323
        operatorCircle = ""
6092 rajveer 4324
 
6289 anupam.sin 4325
    deviceNumberInfo = DeviceNumberInfo()
6336 anupam.sin 4326
    deviceNumberInfo.circleCode = operatorCircle
6289 anupam.sin 4327
    deviceNumberInfo.operatorId = providerId
6313 anupam.sin 4328
    if provider:
4329
        deviceNumberInfo.operatorName = provider.name
6289 anupam.sin 4330
    return deviceNumberInfo
6269 rajveer 4331
 
6591 anupam.sin 4332
def validate_recharge(rechargeType, deviceNumber, userSelectedProviderId, clientAddress):
4333
 
4334
    addressComponents = clientAddress.split('.')
4335
    n = 3
4336
    addressNumber = 0
4337
    for addressComponent in addressComponents :
4338
        addressNumber = addressNumber + (int(addressComponent) * pow(256, n))
4339
        n = n-1
4340
    matchingRow = BlockedIpRange.query.filter(BlockedIpRange.start <= addressNumber).filter(BlockedIpRange.end >= addressNumber).first()
4341
    #if a match is found then check if date has expired.
4342
    if matchingRow :
4343
        #if expiredOn is None that means this range is permanently blocked.
4344
        if matchingRow.expiredOn is None:
4345
            deniedIpAddress = DeniedIpAddress()
4346
            deniedIpAddress.ip = clientAddress
4347
            deniedIpAddress.deniedOn = datetime.datetime.now()
4348
            deniedIpAddress.deviceNumber = deviceNumber
4349
            deniedIpAddress.rechargeType = rechargeType
4350
            session.commit()
4351
            return "Oops! There seems to be a problem. Please try after some time."
4352
        else :
4353
            #if expired is not None and the blockage is still not expired then block the ip.
4354
            if matchingRow.expiredOn > datetime.datetime.now():
4355
                deniedIpAddress = DeniedIpAddress()
4356
                deniedIpAddress.ip = clientAddress
4357
                deniedIpAddress.deniedOn = datetime.datetime.now()
4358
                deniedIpAddress.deviceNumber = deviceNumber
4359
                deniedIpAddress.rechargeType = rechargeType
4360
                session.commit()
4361
                return "Oops! There seems to be a problem. Please try after some time."
4362
 
7792 anupam.sin 4363
    #FIXME : MNP cases are not being handled.
6307 anupam.sin 4364
    deviceNumberInfo = get_service_provider_for_device(rechargeType, deviceNumber)
4365
    if deviceNumberInfo.operatorId == -1:
4366
        return "Oops! There seems to be a problem. Please try after some time."
6336 anupam.sin 4367
    circle = TelecomCircle.query.filter_by(code = deviceNumberInfo.circleCode).first()
6313 anupam.sin 4368
    if circle:
6734 anupam.sin 4369
        serviceAvailability = ServiceAvailability.query.filter_by(circleId = circle.id).filter_by(operatorId = userSelectedProviderId).first()
4370
        if serviceAvailability.permIsServiceAvailable == False or serviceAvailability.tempIsServiceAvailable == False :
4371
 
6313 anupam.sin 4372
            if deviceNumberInfo.operatorName :
6734 anupam.sin 4373
                if serviceAvailability.permIsServiceAvailable == False:
4374
                    return "We currently do not provide service for " + deviceNumberInfo.operatorName + " in " + circle.name + ". We regret the inconvenience."
6314 anupam.sin 4375
                else :
4376
                    return "We are facing technical issues with " + deviceNumberInfo.operatorName + " in " + circle.name + " currently. Please try later." 
6316 anupam.sin 4377
            else :
6734 anupam.sin 4378
                if serviceAvailability.permIsServiceAvailable == False:
4379
                    return "We currently do not provide service for this operator in " + circle.name + ". We regret the inconvenience."
4380
                else:
4381
                    return "We are facing technical issues with this operator in " + circle.name + " currently. Please try later." 
6719 anupam.sin 4382
    totalSuccessfulRechargeAmount = get_previous_transactions(clientAddress)
4383
    if totalSuccessfulRechargeAmount >= 3000 :
4384
        return "You have exceeded your daily recharge limit. Please try after 24 hours."
6269 rajveer 4385
    return "SUCCESS"
6049 rajveer 4386
 
6719 anupam.sin 4387
def get_previous_transactions(clientAddress):
6271 rajveer 4388
    limittime = datetime.datetime.now() - datetime.timedelta(hours=24)
6719 anupam.sin 4389
    totalSuccessfulRechargeAmount = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == 5).filter(RechargeOrder.ipAddress == clientAddress).filter(RechargeOrder.creationTimestamp  > limittime).scalar()
4390
    return totalSuccessfulRechargeAmount    
6269 rajveer 4391
 
6031 rajveer 4392
def update_amount_in_wallet(userId, amount, orderId):
4393
    if amount == 0:
4394
        return
4395
    wallet = get_user_wallet(userId)
4396
    wallet.amount = wallet.amount + amount
4397
 
4398
    history = UserWalletHistory()
4399
    history.amount = amount
4400
    history.orderId = orderId
4401
    history.wallet = wallet
4402
    history.timestamp = datetime.datetime.now()
4403
    session.commit()
6056 amit.gupta 4404
 
6094 rajveer 4405
def get_recharge_orders_for_device(deviceNumber):
4406
    orders = MobileRechargeOrder.query.filter_by(mobileNumber = deviceNumber).all()
4407
    if orders is None:
4408
        orders = DTHRechargeOrder.query.filter_by(dthAccountNumber = deviceNumber).all()
4409
    return orders
4410
 
6154 rajveer 4411
def get_recharge_orders_for_status(status):
4412
    if status == -1:
6161 rajveer 4413
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).all()
6154 rajveer 4414
    else:
6161 rajveer 4415
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = status).all()
6154 rajveer 4416
    return orders
4417
 
6188 rajveer 4418
def get_recharge_statistics():
4419
    rs = RechargeStatistics()
4420
    statusCounts = {}
4421
    operatorCounts = {}
4422
    currentOrders = {}
4423
    amounts = {}
4424
 
4425
    sorders = session.query(RechargeOrder.status, func.count(RechargeOrder.status)).group_by(RechargeOrder.status).all()
4426
    for sorder in sorders:
6190 rajveer 4427
        statusCounts[sorder[0]] = sorder[1]
6188 rajveer 4428
 
4429
    oorders = session.query(MobileRechargeOrder.mobileOperatorId, func.count(MobileRechargeOrder.mobileOperatorId)).group_by(MobileRechargeOrder.mobileOperatorId).all()
4430
    for oorder in oorders:
6190 rajveer 4431
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4432
 
4433
    oorders = session.query(DTHRechargeOrder.dthOperatorId, func.count(DTHRechargeOrder.dthOperatorId)).group_by(DTHRechargeOrder.dthOperatorId).all()
4434
    for oorder in oorders:
6190 rajveer 4435
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4436
 
6219 rajveer 4437
    forders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED).limit(20).all()
6188 rajveer 4438
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED)] = [order.to_thrift_object() for order in forders]
4439
    sorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_SUCCESSFUL).limit(20).all()
6197 rajveer 4440
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_SUCCESSFUL)] = [order.to_thrift_object() for order in sorders]
6216 rajveer 4441
    porders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.PAYMENT_SUCCESSFUL).limit(20).all()
4442
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.PAYMENT_SUCCESSFUL)] = [order.to_thrift_object() for order in porders]
6238 rajveer 4443
    rorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED).limit(20).all()
4444
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED_REFUNDED)] = [order.to_thrift_object() for order in rorders]
6188 rajveer 4445
 
6190 rajveer 4446
    twa = session.query(func.sum(UserWallet.amount)).one()
4447
    tra = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4448
    gwa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId > 100000).one()
6278 rajveer 4449
    #tpa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId < 100000).one()
6482 rajveer 4450
    tpa = session.query(func.sum(RechargeOrder.totalAmount-RechargeOrder.walletAmount-RechargeOrder.couponAmount)).filter(RechargeOrder.status.in_((RechargeOrderStatus.RECHARGE_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED, RechargeOrderStatus.PAYMENT_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED_REFUNDED))).one()
4451
    tda = session.query(func.sum(RechargeOrder.couponAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4452
 
6346 rajveer 4453
    balance = RechargeService.getBalance()
6305 rajveer 4454
    amounts['(a) Total Payment Amount'] = tpa[0]
4455
    amounts['(b) Gift Wallet Amount'] = gwa[0]
4456
    amounts['(c) Total Wallet Amount'] = twa[0]
4457
    amounts['(d) Total Recharge Amount'] = tra[0]
4458
    amounts['(e) Account Balance'] = balance
6482 rajveer 4459
    amounts['(f) Discount Balance'] = tda[0]
6278 rajveer 4460
    #amounts['Total Payment Amount'] = tra[0] + twa[0] - gwa[0]
6524 rajveer 4461
    amounts['Saholic Mismatch = (a+b+f-c-d)'] = tpa[0] + gwa[0] + tda[0] - tra[0] - (twa[0] + 63774)
4462
    amounts['SpiceDeck Mismatch = (d-e)'] = tra[0] + balance - 750000 
6278 rajveer 4463
 
6337 rajveer 4464
    '''
6318 rajveer 4465
    if amounts['SpiceDeck Mismatch = (d-e)'] != -739:
4466
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "SpiceDeck Account mismatch of amount " + str(amounts['SpiceDeck Mismatch = (d-e)']), "", [], [], [])
4467
    if amounts['Saholic Mismatch = (a+b-c-d)'] != -1919:
4468
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "Saholic Recharge Account mismatch of amount " + str(amounts['Saholic Mismatch = (a+b-c-d)']), "", [], [], [])
6337 rajveer 4469
    '''
6318 rajveer 4470
 
6188 rajveer 4471
    rs.statusCounts = statusCounts
4472
    rs.operatorCounts = operatorCounts    
4473
    rs.currentOrders = currentOrders
4474
    rs.amounts = amounts
4475
 
4476
    return rs
4477
 
4478
 
6159 rajveer 4479
def get_plans_for_operator(operator_id):
4480
    return RechargePlan.query.filter_by(operatorId = operator_id).all()
4481
 
6056 amit.gupta 4482
def get_recharge_orders_for_transaction(txId):
4483
    return RechargeOrder.query.filter_by(transaction_id = txId).first()
6102 rajveer 4484
 
6285 rajveer 4485
def enqueue_recharge_info_email(recharge_order, gvs={}):
6102 rajveer 4486
    status = ""
4487
    message = ""
4488
    html_header = """
4489
 
4490
    <html>
4491
    <body>
4492
    <div>
4493
        <p>
4494
            Hello $email,<br /><br />
6127 rajveer 4495
            Thanks for placing recharge order with us. Following are the details of your recharge order:
6102 rajveer 4496
        </p>
4497
        <div>
6136 rajveer 4498
            Order Id : $order_id <br/>
4499
            Order Date : $order_date <br/>
4500
            Order Amount : Rs. $order_amount <br/>
4501
            Order Status : $order_status <br/>
4502
            Device Number : $device_number <br/>
4503
            Service Provider : $service_provider <br/>
6102 rajveer 4504
        </div>
6348 rajveer 4505
    <br />
6102 rajveer 4506
    """
6288 rajveer 4507
 
4508
    FailureReasonMap = {}
4509
    FailureReasonMap["Invalid Amount"] = "the amount you tried seems to be invalid. Please try another amount."
4510
    FailureReasonMap["Customer Exceeded Daily Limit"] = "you have exceeded daily recharge limit for this number. Please try after 12 hours."
6399 rajveer 4511
    FailureReasonMap["Invalid Device Number"] = "it seems that your device number is not being recognized by selected operator. Please make sure the number you tried is correct."
6288 rajveer 4512
 
4513
    failureReason = FailureReasonMap.get(recharge_order.description)
4514
    if failureReason is None:
4515
        failureReason = "of network failure."
6102 rajveer 4516
    if recharge_order.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4517
        status = "Recharge Successful"
4518
        message = ""
6444 rajveer 4519
        if recharge_order.couponAmount > 0:
4520
            message = message + "<b>You have used coupon " + recharge_order.couponCode + " and got discount of Rs. " + str(recharge_order.couponAmount) + ".</b>" 
4521
 
6102 rajveer 4522
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED:
4523
        status = "Recharge Failed"
6127 rajveer 4524
        message = """
6288 rajveer 4525
                We could not process your recharge because $failureReason We have credited the amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
6127 rajveer 4526
                """
6206 rajveer 4527
    elif recharge_order.status == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6102 rajveer 4528
        status = "Recharge Under Process"
6127 rajveer 4529
        message = """
6288 rajveer 4530
                Your Payment was successful but due to some internal error with the operator's system we are not sure if the recharge was successful. In case your recharge is not processed, we will credit amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
6127 rajveer 4531
                """
6279 rajveer 4532
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
4533
        status = "Recharge Failed, Amount Refunded"
4534
        message = """
4535
                It seems operator could not process your recharge request. We are crediting the refund amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
4536
                """
6285 rajveer 4537
    if len(gvs) > 0:
6340 rajveer 4538
        message = message  + '<br />  You have been awarded with following Gift Voucher(s). You can redeem Gift Voucher(s) to purchase any product for Rs. 5000 and above using credit/debit card and net banking. <a href="$source_url/static/giftvoucher-offer">More details</a>'
6330 rajveer 4539
        message = message + " <br />  <b>Voucher Code &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Amount</b>"
6285 rajveer 4540
        for gv in gvs.keys():
4541
            gvAmount = gvs.get(gv)
6330 rajveer 4542
            message = message + " <br />  <b>" + gv + "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rs. "  + str(gvAmount) + "</b>"
6285 rajveer 4543
 
6114 rajveer 4544
    message = message  + '<br />  In case of any problem, please  <a href="$source_url/contact-us">contact us</a>'
6102 rajveer 4545
 
6136 rajveer 4546
    html_header = html_header + message
6102 rajveer 4547
    html_footer = """
4548
    <p>
4549
        Best Wishes,<br />
4550
        $source_name Team
4551
    </p>
4552
    </div>
4553
    </body>
4554
    </html>
4555
    """
4556
 
6125 rajveer 4557
    if isinstance(recharge_order, MobileRechargeOrder):
4558
        deviceNumber = recharge_order.mobileNumber
4559
        providerName = get_provider(recharge_order.mobileOperatorId).name
4560
    if isinstance(recharge_order, DTHRechargeOrder):
4561
        deviceNumber = recharge_order.dthAccountNumber
4562
        providerName = get_provider(recharge_order.dthOperatorId).name
4563
 
6127 rajveer 4564
    display_order_id = recharge_order.idPrefix + str(recharge_order.id)
6102 rajveer 4565
    email = recharge_order.userEmailId
4566
    dt = datetime.datetime.strptime(str(recharge_order.creationTimestamp), "%Y-%m-%d %H:%M:%S")
4567
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
4568
 
6288 rajveer 4569
    email_header = Template(html_header).substitute(dict(order_id = display_order_id, order_date = formated_order_date, email = email, source_url = source_url, order_amount = recharge_order.totalAmount, order_status = status, device_number = deviceNumber, service_provider = providerName, failureReason = failureReason))
6102 rajveer 4570
    email_footer = Template(html_footer).substitute(dict(source_url = source_url, source_name = source_name))
4571
 
4572
    try:
4573
        helper_client = HelperClient().get_client()
6906 rajveer 4574
        helper_client.saveUserEmailForSending([email], "", source_name + " - Recharge Order Details", email_header + email_footer, str(recharge_order.id), "RechargeInfo", [], [])
6102 rajveer 4575
        return True
4576
    except Exception as e:
4577
        print e
4578
        return False
4579
 
6307 anupam.sin 4580
def get_recharge_denominations(operator_id, circleCode, denomination_type):
4581
    circle_id = TelecomCircle.query.filter_by(code = circleCode).first().id
6289 anupam.sin 4582
    return RechargeDenomination.query.filter_by(operatorId = operator_id).filter_by(circleId = circle_id).filter_by(denominationType = denomination_type).all()
6371 rajveer 4583
 
4584
def update_availability_status(operatorId, circleId, isAvailable):
4585
    serviceAvailability = ServiceAvailability.query.filter_by(circleId = circleId).filter_by(operatorId = operatorId).first()
6734 anupam.sin 4586
    serviceAvailability.tempIsServiceAvailable = isAvailable
6371 rajveer 4587
    session.commit()
4588
 
6389 rajveer 4589
def get_misc_charges(transactionId):
4590
    retCharges = {}
4591
    miscCharges = MiscCharges.get_by(transaction_id = transactionId)
4592
    if miscCharges:
6426 rajveer 4593
        retCharges[1] = miscCharges.chargeAmount 
6389 rajveer 4594
    return retCharges
6396 amit.gupta 4595
 
4596
def get_available_emi_schemes():
4597
    t_emi_schemes = []
4598
    emi_schemes = EmiScheme.query.all()
4599
    if emi_schemes:
4600
        t_emi_schemes = [to_t_emi_scheme(emi_scheme) for emi_scheme in emi_schemes]
4601
    return t_emi_schemes
6389 rajveer 4602
 
6507 anupam.sin 4603
def refund_recharge_order(rechargeOrderId):
4604
    try :
4605
        rechargeOrder = RechargeOrder.query.filter_by(id = rechargeOrderId).first()
4606
        wallet = UserWallet.query.filter_by(userId = rechargeOrder.userId).first()
4607
    except:
4608
        return False
4609
 
4610
    paidAmount = rechargeOrder.totalAmount - rechargeOrder.walletAmount - rechargeOrder.couponAmount
4611
    amountToRefund = 0
4612
    status = None
4613
    if (paidAmount <= wallet.amount) :
4614
        amountToRefund = paidAmount
4615
        status = RechargeOrderStatus.REFUNDED
4616
    else :
4617
        amountToRefund = wallet.amount
4618
        status = RechargeOrderStatus.PARTIALLY_REFUNDED
4619
 
4620
    update_amount_in_wallet(rechargeOrder.userId, -amountToRefund, rechargeOrderId)
4621
 
4622
    try:    
4623
        pc = PaymentClient().get_client()
4624
        if pc.refundPayment(rechargeOrder.transaction_id, amountToRefund, True) :
4625
            rechargeOrder.status = status
6515 anupam.sin 4626
            rechargeOrder.refundTimestamp = datetime.datetime.now()
6507 anupam.sin 4627
            session.commit()
4628
            return True
4629
        else :
4630
            update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4631
 
4632
    except:
4633
        update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4634
 
4635
    return False 
4636
 
6821 amar.kumar 4637
def get_physical_orders(from_date, to_date):
4638
    query = Order.query.filter(Order.created_timestamp >from_date).filter(Order.created_timestamp < to_date).filter(Order.status>=2)
4639
    return query.all()
4640
 
6507 anupam.sin 4641
 
766 rajveer 4642
def close_session():
4643
    if session.is_active:
4644
        print "session is active. closing it."
2783 chandransh 4645
        session.close()
3376 rajveer 4646
 
4647
def is_alive():
4648
    try:
4649
        session.query(Transaction.id).limit(1).one()
4650
        return True
4651
    except:
6000 mandeep.dh 4652
        return False
4653
 
6906 rajveer 4654
def get_document(docType, docSource):
4655
    document = DocumentStore.get_by(docType = docType, docSource = docSource)
4656
    if document:
4657
        return document.document
4658
    else:
7040 amar.kumar 4659
        return bin(0)
6906 rajveer 4660
 
7075 rajveer 4661
def retrieve_invoice(orderId, userId):
4662
    order = get_order(orderId)
4663
    if order.customer_id != userId:
4664
        return bin(0)
6988 rajveer 4665
    strOrderId = '0'*(10-len(str(orderId)))+str(orderId)
7072 rajveer 4666
    filename = "/SaholicInvoices/" + strOrderId[0:2] + "/" + strOrderId[2:4] + "/" + strOrderId[4:6] + "/" + str(orderId) + ".pdf"  
6988 rajveer 4667
    file = open(filename, "rb")
4668
    pdfFile = file.read()
4669
    return pdfFile
4670
 
6906 rajveer 4671
def myFirstPage(canvas, doc):
4672
    canvas.saveState()
6916 anupam.sin 4673
    canvas.setTitle("Theft-Insurance-Policy")
6906 rajveer 4674
    canvas.restoreState()
4675
 
4676
 
4677
def __generate_policy_doc(order, filename):
6903 anupam.sin 4678
    PAGE_HEIGHT=defaultPageSize[1]; PAGE_WIDTH=defaultPageSize[0]
4679
    styles = getSampleStyleSheet()
4680
    styles.add(ParagraphStyle(name='left', leftIndent=12,fontSize=11), alias='li')
4681
    styles.add(ParagraphStyle(name='bullet', bulletIndent=24, leftIndent=24), alias='bull')
6916 anupam.sin 4682
    styles.add(ParagraphStyle(name='insurerName', alignment=TA_CENTER, fontName="Times-Bold", fontSize=16), alias='iN')
4683
    styles.add(ParagraphStyle(name='insurerAdd', alignment=TA_CENTER, fontName="Helvetica",leading=15, fontSize=12), alias='iA')
4684
    styles.add(ParagraphStyle(name='subHeading', alignment=TA_CENTER, fontName="Helvetica", fontSize=13), alias='sH')
6903 anupam.sin 4685
 
6914 rajveer 4686
    invoiceNumber = str(order.invoice_number)
6906 rajveer 4687
    billing_timestamp = str(order.billing_timestamp.date()) 
6903 anupam.sin 4688
 
6906 rajveer 4689
    doc = SimpleDocTemplate(filename)
6916 anupam.sin 4690
    Story = [Spacer(0, 0)]
6903 anupam.sin 4691
    style = styles["Normal"]
6916 anupam.sin 4692
 
4693
 
4694
    file_name = os.path.dirname(os.path.realpath(__file__)) + '/../resources/nia-logo.jpg'
4695
    image = Image(file_name, width=100, height=100)
4696
    Story.append(image)
4697
    Story.append(Spacer(1,0.2*inch))
4698
 
4699
    text = ("""<u>The New India Assurance Company Limited</u>""") 
4700
    p = Paragraph(text, styles['insurerName'])
4701
    Story.append(p)
4702
    Story.append(Spacer(1,0.2*inch))
4703
 
4704
    text = ("""DO-IX, 35/1, Fortune Park, 1st Floor, Park Road, Tasker Town, Shivajinagar, Bangalore  560051""") 
4705
    p = Paragraph(text, styles['insurerAdd'])
4706
    Story.append(p)
4707
    Story.append(Spacer(1,0.3*inch))
4708
 
4709
    text = ("""MOBILE HAND SET INSURANCE – THEFT & BURGLARY RISKS ONLY""")
4710
    p = Paragraph(text, styles['subHeading'])
4711
    Story.append(p)
4712
    Story.append(Spacer(1,1*inch))
4713
 
6903 anupam.sin 4714
    text = ("""<u><b>Subject Matter Of Insurance</b></u> : <i>New Mobile Handsets</i> alone and <i>Tablets with 'Voice Calls'</i> only. 
4715
    Sold 'online' by <b>Spice Online Retail Private Limited, New Delhi</b>, to its customers.""") 
4716
    p = Paragraph(text, style)
4717
    Story.append(p)
4718
    Story.append(Spacer(1,0.2*inch))
4719
    text = ("""Insurer will indemnify the Insured in the event of Theft/Burglary of <i>Mobile Handsets</i> 
6914 rajveer 4720
    alone and <i>Tablets with 'Voice Calls'</i> only sold as per Invoice No. %s
6903 anupam.sin 4721
    dated %s and insured with THE NEW INDIA ASSURANCE COMPANY LIMITED, BANGALORE, as per Policy No. 671700/46/12/2400000008,  
4722
    for a period of 12 months from the date and time of delivery of Mobile Handset to the customer.""" % (invoiceNumber, billing_timestamp)) 
4723
    p = Paragraph(text, style)
4724
    Story.append(p)
4725
    Story.append(Spacer(1,0.2*inch))
4726
    text = ("""<b>WARRANTY</b> -  Warranted that the Mobile Handset sold during the Policy Period of 25/02/2013 to 24/02/2014
4727
             are only covered irrespective of date of delivery to the customer""")
4728
    p = Paragraph(text, style)
4729
    Story.append(p)
4730
    Story.append(Spacer(1,0.2*inch))
6915 anupam.sin 4731
    text = ("<b>INSURER</b> -The New India Assurance company limited.")
6903 anupam.sin 4732
    p = Paragraph(text, style)
4733
    Story.append(p)
4734
    Story.append(Spacer(1,0.2*inch))
4735
    text = ("<b>INSURED</b> - Purchaser of the Mobile Handset OR his/her spouse or children. If the Purchaser is a ‘Company’, user is the duly authorised person.") 
4736
    p = Paragraph(text, style)
4737
    Story.append(p)
4738
    Story.append(Spacer(1,0.2*inch))
4739
    text = ("<b>GEOGRAPHICAL LIMIT</b> – World-wide") 
4740
    p = Paragraph(text, style)
4741
    Story.append(p)
4742
    Story.append(Spacer(1,0.2*inch))
4743
    text = ("<b>RISK COVERAGE</b> – Theft and/or burglary only") 
4744
    p = Paragraph(text, style)
4745
    Story.append(p)
6916 anupam.sin 4746
    Story.append(Spacer(1,0.4*inch))
6915 anupam.sin 4747
    text = ("Terms and Conditions of Insurance:") 
4748
    p = Paragraph(text, styles["h2"])
4749
    Story.append(p)
4750
    Story.append(Spacer(1,0.1*inch))
4751
    text = ("""Insurance Premium paid will not be refunded.""")
4752
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4753
    Story.append(p)
4754
    Story.append(Spacer(1,0.1*inch))
6921 anupam.sin 4755
    text = ("""Claims will be settled by UIB on behalf of The New India Assurance Co. Ltd.<br></br>
4756
            Saholic.com will not be responsible for claim approval and disbursement.""")
4757
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4758
    Story.append(p)
4759
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4760
    text = ("""Insurance will be invalidated for returned products.""")
4761
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4762
    Story.append(p)
6921 anupam.sin 4763
    Story.append(Spacer(1,0.3*inch))
6903 anupam.sin 4764
    text = ("Exclusions:") 
4765
    p = Paragraph(text, styles["h2"])
4766
    Story.append(p)
4767
    Story.append(Spacer(1,0.1*inch))
4768
    text = ("Insurer is not liable") 
4769
    p = Paragraph(text, styles["left"])
4770
    Story.append(p)
4771
    Story.append(Spacer(1,0.1*inch))
4772
    text = ("If the handset is not connected to Mobile Service Provider Network")
4773
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4774
    Story.append(p)
4775
    Story.append(Spacer(1,0.1*inch))
4776
    text = ("Caused by incorrect storage, poor care and maintenance, careless use, negligence.")
4777
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4778
    Story.append(p)
4779
    Story.append(Spacer(1,0.1*inch))
4780
    text = ("Due to mysterious disappearance, forgotten or misplaced or Lost or if handset is left unattended at any point of time.")
4781
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4782
    Story.append(p)
4783
    Story.append(Spacer(1,0.1*inch))
4784
    text = ("Caused by war, war like operation, act of foreign enemy, civil war, rebellion, civil commotion, military usurped power, seizure, capture, confiscation, arrests, restrains and detainment by order of any Government or any other Authority.")
4785
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4786
    Story.append(p)
4787
    Story.append(Spacer(1,0.1*inch))
4788
    text = ("Caused whilst engaging in criminal acts.")
4789
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4790
    Story.append(p)
4791
    Story.append(Spacer(1,0.1*inch))
4792
    text = ("Caused by consequential loss or damage of whatsoever nature or any costs incurred in connection with claim under this policy, including postage, transit costs and reconnection cost.")
4793
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4794
    Story.append(p)
4795
    Story.append(Spacer(1,0.1*inch))
4796
    text = ("Loss of mobile handset due to theft from an unattended vehicle unless the vehicle is of  fully enclosed saloon type having at time all the doors/windows and other opening securely locked and properly fastened.")
4797
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4798
    Story.append(p)
4799
    Story.append(Spacer(1,0.1*inch))
4800
    text = ("Loss of mobile handset due to theft from the building unless there is visible forcible entry/exit into/from the building.")
4801
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4802
    Story.append(p)
4803
    Story.append(Spacer(1,0.1*inch))
4804
    text = ("If the documents are found to be tampered; non-disclosure of material fact, fraud/misrepresentation.")
4805
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4806
    Story.append(p)
4807
    Story.append(Spacer(1,0.1*inch))
4808
    text = ("The policy is not transferable.")
4809
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4810
    Story.append(p)
4811
    Story.append(Spacer(1,0.2*inch))
4812
 
4813
    text = ("Claim Procedure:") 
4814
    p = Paragraph(text, styles["h2"])
4815
    Story.append(p)
4816
    Story.append(Spacer(1,0.1*inch))
4817
    text = ("""For Theft or Burglary of the handset immediate intimation to be given
4818
     to the police within 48 hours of occurrence of incident and proper documents to be obtained 
4819
     and inform the service provider within 48 hours about theft of handset in order to block the SIM services.""")
4820
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4821
    Story.append(p)
4822
    Story.append(Spacer(1,0.1*inch))
4823
    text = ("""To intimate Insurance Company about the loss of Mobile Handset within 48 hours 
6915 anupam.sin 4824
     through Call Centre No.022-49107910 OR through e-mail <u>saholic.claims@universalinsurance.co.in</u> OR through 
6903 anupam.sin 4825
     written communication to <i>Universal Insurance brokers (UIB) No.304, Commerce House, 9/1,Cunningham Road, Bangalore – 560052</i>.""")
4826
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4827
    Story.append(p)
4828
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4829
    text = ("""Claim documents can be downloaded through UIB Website <u>http://www.universalinsurance.co.in/mobileinsurance/claiminfo.html</u>
4830
    <br></br>To know or track your claim please contact Call Centre No. 022-49107910 of Universal Insurance brokers (UIB). """)
6903 anupam.sin 4831
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4832
    Story.append(p)
4833
    Story.append(Spacer(1,0.1*inch))
4834
    text = ("""All the completed claim documents to reach ‘Universal Insurance Brokers (UIB)’ office 
4835
    at <i>No.304, Commerce House, 9/1, Cunningham Road, Bangalore – 560052</i> <b>within 21 days</b>.""")
4836
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4837
    Story.append(p)
4838
    Story.append(Spacer(1,0.2*inch))
4839
 
4840
 
4841
    text = ("Excess(Minimum Deduction):") 
4842
    p = Paragraph(text, styles["h2"])
4843
    Story.append(p)
4844
    Story.append(Spacer(1,0.1*inch))
4845
    text = ("""The excess will be 5% of the value of each claim subject to a minimum of Rs.500/-""")
4846
    p = Paragraph(text, styles["left"])
4847
    Story.append(p)
4848
    Story.append(Spacer(1,0.2*inch))
4849
 
4850
    text = ("Depreciation:") 
4851
    p = Paragraph(text, styles["h2"])
4852
    Story.append(p)
4853
    Story.append(Spacer(1,0.1*inch))
4854
 
4855
    text = ("For 0 – 60 days, 15%")
4856
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4857
    Story.append(p)
4858
    Story.append(Spacer(1,0.1*inch))
4859
 
4860
    text = ("61-150 days, 30%")
4861
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4862
    Story.append(p)
4863
    Story.append(Spacer(1,0.1*inch))
4864
 
4865
    text = ("151 – 365 days, 45%")
4866
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4867
    Story.append(p)
4868
    Story.append(Spacer(1,0.4*inch))
4869
 
4870
    text = ("<i>Insurance is a subject matter of solicitation.</i>")
4871
    p = Paragraph(text, style)
4872
    Story.append(p)
4873
    Story.append(Spacer(1,0.2*inch))
4874
 
6906 rajveer 4875
    doc.build(Story, onFirstPage=myFirstPage)
6980 anupam.sin 4876
 
4877
def drawLine(Story, style):
4878
    Story.append(Paragraph('-'*40, style))
6915 anupam.sin 4879
 
6980 anupam.sin 4880
def generateHotSpotInvoice():
4881
 
4882
    ##########TO BE PASSED TO THIS METHOD####################################
4883
    #########################################################################
4884
    filename = "/home/anupam/test.pdf"                             ##########
4885
    itemCode = "SPICEMI450WHT"                                     ##########
4886
    lotNumber = "12345678901234"                                   ##########
4887
    itemName = "Spice Stellar Craze Mi-450 White"                  ##########
4888
    qty = 1                                                        ##########
4889
    unitPrice = 3099.50                                            ##########
4890
    vat = 310.23                                                   ##########
4891
    billingTime = datetime.datetime.now()                          ##########
4892
    invNum = "885182994"                                           ##########
4893
    counter = 1                                                    ##########
4894
    ourInvoiceNum = "209809"                                       ##########
4895
    customerId = "12345678909"                                     ##########
4896
    customerName = "ANUPAM PRATAP SINGH"                           ##########
4897
    telNum = ""                                                    ##########
4898
    #########################################################################
4899
 
4900
    PAGE_HEIGHT=defaultPageSize[1];
4901
    styles = getSampleStyleSheet()
4902
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
4903
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
4904
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
4905
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
4906
 
4907
    Story = []
4908
    prologueStyle = styles["prologue"]
4909
    lineStyle = styles["line"]
4910
    textStyle = styles["text"]
4911
    epilogueStyle = styles["epilogue"]
4912
 
4913
    doc = BaseDocTemplate(filename,showBoundary=0)
4914
 
4915
    #Two Columns
4916
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
4917
 
4918
 
4919
 
4920
    Story.append(Paragraph("""Spice Retail Limited<br></br>
4921
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
4922
        2,Kalkaji Industrial Area,New Delhi<br></br>
4923
          .<br></br>
4924
        TIN NO. 07430284979<br></br>
4925
        Service Tax No:AAACM0294PST001<br></br>
4926
        D U P L I C A T E<br></br>
4927
        I N V O I C E<br></br>""", prologueStyle))
4928
    drawLine(Story, lineStyle)
4929
 
4930
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4931
    Story.append(Paragraph("{0:8s}{1:>5d}{2:>11s}{3:>11s}".format('COUNTER:', counter, "CASHIER:", "SUPERADMIN").replace(" ", "&nbsp;"), textStyle))
4932
    Story.append(Paragraph("MN INV NO&amp;DT: {0:<13s}{1:%d/%m/%Y}   ".format(ourInvoiceNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4933
    drawLine(Story, lineStyle)
4934
 
4935
    Story.append(Paragraph("{0:<13s}{1:<27s}".format("CUSTOMER ID:", customerId).replace(" ", "&nbsp;"), textStyle))
4936
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName + " " + ourInvoiceNum).replace(" ", "&nbsp;"), textStyle))
4937
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
4938
    drawLine(Story, lineStyle)
4939
 
4940
    Story.append(Paragraph("ITEM" + "&nbsp;"*12 + "LOT NUMBER<br></br>" + \
4941
                            "&nbsp;ITEM NAME<br></br>" + \
4942
                            "&nbsp;"*5 + "QTY" + "&nbsp;"*21 + "AMOUNT(INR)", textStyle))
4943
    drawLine(Story, lineStyle)
4944
 
4945
    Story.append(Paragraph(('{0:<16s}{1:24s}').format(itemCode, lotNumber).replace(' ', '&nbsp;'),textStyle))
4946
    Story.append(Paragraph((' {0:<39s}').format(itemName).replace(' ', '&nbsp;'),textStyle))
4947
    Story.append(Paragraph(('{0:<3d}{1:>10s}{2:13.2f}{3:14.2f}').format(qty, 'PCS', unitPrice, qty*unitPrice).replace(' ', '&nbsp;'),textStyle))
4948
    Story.append(Paragraph(('{0:<3s}{1:37.2f}').format("VAT", vat).replace(' ', '&nbsp;'),textStyle))
4949
    Story.append(Paragraph(('{0:<10s}{1:30.2f}').format("ITEM TOTAL", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4950
 
4951
    drawLine(Story, lineStyle)
4952
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("GROSS TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4953
    drawLine(Story, lineStyle)
4954
 
4955
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4956
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET VAT:","INR", vat).replace(' ', '&nbsp;'),textStyle))
4957
    drawLine(Story, lineStyle)
4958
 
4959
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("SPICE ONLINE:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4960
    drawLine(Story, lineStyle)
4961
 
4962
    Story.append(Paragraph(('{0:16s}{1:>4d}').format("NUMBER OF ITEMS:",qty,).replace(' ', '&nbsp;'),textStyle))
4963
    Story.append(Paragraph(('{0:16s}{1:>9.6f}').format("TOTAL ITEMS    :",qty,).replace(' ', '&nbsp;'),textStyle))
4964
 
4965
    Story.append(Paragraph("Goods once Sold Will not be taken back.<br></br>All Disputes subject to Delhi Jurisdiction",epilogueStyle))
4966
 
4967
 
4968
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
4969
 
4970
    #start the construction of the pdf
4971
    doc.build(Story)
4972
 
6985 anupam.sin 4973
def change_shipping_address(orderId, line1, line2, city, state, pin):
4974
    order = Order.get_by(id = orderId)
4975
    if order:
4976
        order.customer_address1 = line1
4977
        order.customer_address2 = line2
4978
        order.customer_city = city
4979
        order.customer_state = state
7364 manish.sha 4980
 
4981
        # Start:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionality
4982
        if order.customer_pincode != pin :
4983
            type = DeliveryType.PREPAID
4984
            if order.cod:
4985
                type = DeliveryType.COD
4986
            logistics_client = LogisticsClient().get_client()
4987
            logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, pin, type)
4988
 
4989
            # Check for new estimate. Raise exception if new address is not serviceable
4990
            if logistics_info.deliveryTime == -1:
4991
                raise TransactionServiceException(1, 'Location not serviceable')
4992
 
4993
            # COD services are not available everywhere
4994
            if order.cod:
4995
                if not logistics_info.codAllowed:
4996
                    raise TransactionServiceException(2, 'COD service not available')
4997
 
4998
            logistics_info_new = logistics_client.getLogisticsInfo(pin, order.lineitems[0].item_id, type, PickUpType.COURIER)
4999
            order.tracking_id = logistics_info_new.airway_billno
5000
            order.airwaybill_no = logistics_info_new.airway_billno
5001
            order.logistics_provider_id = logistics_info_new.providerId
5002
            current_time = datetime.datetime.now()
5003
 
5004
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
5005
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
5006
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
5007
            new_expected_shipping_time_cod = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
5008
            new_expected_shipping_time_prepaid = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
5009
 
5010
            if order.cod:
5011
                if order.expected_shipping_time.date() == new_expected_shipping_time_cod.date() :
5012
                    if order.otg :
5013
                        order.otg = logistics_info.otgAvailable 
5014
                else:
5015
                    if order.otg:
5016
                        order.otg = False
5017
                order.expected_shipping_time = new_expected_shipping_time_cod
5018
                order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
5019
                order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
5020
            else:
5021
                if order.expected_shipping_time.date() == new_expected_shipping_time_prepaid.date() :
5022
                    if order.otg :
5023
                        order.otg = logistics_info.otgAvailable 
5024
                else:
5025
                    if order.otg:
5026
                        order.otg = False
5027
                order.expected_shipping_time = new_expected_shipping_time_prepaid
5028
                order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
5029
                order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
5030
 
5031
        order.customer_pincode = pin
5032
        # End:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionality
6985 anupam.sin 5033
        session.commit()
5034
        return True
5035
    return False
5036
 
7084 rajveer 5037
def get_recharge_transactions(storeId):
5038
    query = RechargeTransaction.query.filter(RechargeTransaction.storeId == storeId)
5039
    return query.all()
5040
 
7151 amit.gupta 5041
def get_recharge_trans(storeId, startdate,enddate, status):
5042
    if startdate == -1:
5043
        startdate = None
5044
    if enddate == -1:
5045
        enddate = None
5046
    if storeId== 0:
5047
        storeId = None
5048
    if status == 0:
5049
        status = None    
5050
 
5051
    query = RechargeTransaction.query
5052
    if storeId is not None:
5053
        query = query.filter(RechargeTransaction.storeId == storeId)
5054
    if status is not None:
5055
        query = query.filter(RechargeTransaction.status == status)
7169 anupam.sin 5056
 
5057
    if status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED :
5058
        query.filter(cast(RechargeTransaction.responseTime, DATE) == enddate)
7151 amit.gupta 5059
 
7169 anupam.sin 5060
    else :
5061
        if startdate is not None and enddate is not None:
5062
            startdate = to_py_date(startdate).date()
5063
            enddate = to_py_date(enddate).date()
5064
            if startdate == enddate:
5065
                query = query.filter(cast(RechargeTransaction.transactionTime, DATE) == enddate)
5066
            elif enddate < startdate:
5067
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), enddate, startdate))
5068
            else:
5069
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), startdate, enddate))
5070
        elif startdate is not None:
5071
            startdate = to_py_date(startdate).date()
5072
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) >= startdate)
5073
        elif enddate is not None:
5074
            enddate = to_py_date(enddate).date()
5075
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) <= enddate)
5076
 
7151 amit.gupta 5077
    return query.all()    
5078
 
7243 rajveer 5079
def update_recharge_transaction_status(id, status):
7127 rajveer 5080
    rechargeTransaction = RechargeTransaction.get_by(id=id)
7163 rajveer 5081
    if status in (RechargeOrderStatus.RECHARGE_FAILED_REFUNDED, RechargeOrderStatus.RECHARGE_FAILED):
5082
        rechargeTransaction.status = status
7243 rajveer 5083
        rechargeTransaction.responseTime = datetime.datetime.now() 
7127 rajveer 5084
 
5085
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
5086
        wallet = WalletForCompany.get_by(companyId=store.companyId)
5087
        wh = WalletHistoryForCompany()
5088
        wh.walletId = wallet.id
5089
        wh.amount = rechargeTransaction.amount
5090
        wh.transactionTime = rechargeTransaction.responseTime
5091
        wh.openingBal = wallet.amount
5092
        wh.closingBal = wallet.amount + wh.amount
5093
        wh.referenceNumber = rechargeTransaction.id 
5094
        wh.description = "Credited amount"
5095
 
5096
        wallet.amount = wallet.amount + rechargeTransaction.amount
5097
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
5098
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
5099
        session.commit()
7163 rajveer 5100
 
5101
    if status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
5102
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
5103
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
5104
        session.commit()
5105
 
5106
 
7073 anupam.sin 5107
def create_recharge_transaction(t_recharge):
7163 rajveer 5108
    dt = datetime.datetime.now() - datetime.timedelta(minutes=10)
5109
    txns = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == t_recharge.deviceNum).filter(RechargeTransaction.transactionTime > dt).all()
5110
    if txns:
5111
        raise TransactionServiceException(898, "In last 10 minutes you had already recharged this mobile number. Please try after sometime.")
7073 anupam.sin 5112
    rechargeTransaction = RechargeTransaction()
5113
    rechargeTransaction.amount = t_recharge.amount
7096 anupam.sin 5114
    rechargeTransaction.circleId = t_recharge.circleId
7073 anupam.sin 5115
    rechargeTransaction.deviceNum = t_recharge.deviceNum
5116
    rechargeTransaction.deviceType = t_recharge.deviceType
5117
    rechargeTransaction.discount = t_recharge.discount
5118
    rechargeTransaction.email = t_recharge.email
5119
    rechargeTransaction.name = t_recharge.name
5120
    rechargeTransaction.cafNum = t_recharge.cafNum
5121
    rechargeTransaction.simNum = t_recharge.simNum
5122
    rechargeTransaction.isFrc = t_recharge.isFrc
5123
    rechargeTransaction.status = RechargeOrderStatus.INIT
5124
    rechargeTransaction.storeId = t_recharge.storeId
5125
    rechargeTransaction.transactionTime = datetime.datetime.now()
7075 rajveer 5126
    rechargeTransaction.operatorId = t_recharge.operatorId
5127
    rechargeTransaction.plan = t_recharge.plan
7080 anupam.sin 5128
    rechargeTransaction.ipAddress = t_recharge.ipAddress
7096 anupam.sin 5129
    rechargeTransaction.paymentAmount = t_recharge.paymentAmount
7139 amit.gupta 5130
    rechargeTransaction.payMethod = t_recharge.payMethod
7075 rajveer 5131
 
5132
    store = HotspotStore.get_by(id=rechargeTransaction.storeId)
7304 rajveer 5133
    if not rechargeTransaction.circleId:
5134
        rechargeTransaction.circleId = store.circleId
5135
 
7075 rajveer 5136
    wallet = WalletForCompany.get_by(companyId=store.companyId)
5137
    if store.availableLimit < rechargeTransaction.amount or wallet.amount < rechargeTransaction.amount:
5138
        raise TransactionServiceException(898, "Either wallet amount for company or available limit for store is less than recharge amount.")
7249 rajveer 5139
 
7075 rajveer 5140
    wh = WalletHistoryForCompany()
5141
    wh.walletId = wallet.id
5142
    wh.amount = -rechargeTransaction.amount
5143
    wh.transactionTime = rechargeTransaction.transactionTime
5144
    wh.openingBal = wallet.amount
5145
    wh.closingBal = wallet.amount + wh.amount
5146
    wh.description = "Debited amount"
5147
 
5148
    wallet.amount = wallet.amount - rechargeTransaction.amount
5149
    store.availableLimit = store.availableLimit - rechargeTransaction.amount
7076 rajveer 5150
    store.collectedAmount = store.collectedAmount + rechargeTransaction.amount - rechargeTransaction.discount 
7075 rajveer 5151
    session.commit()
5152
 
7249 rajveer 5153
    wh.referenceNumber = rechargeTransaction.id
5154
    session.commit()
5155
 
5156
 
7101 rajveer 5157
    strProviderCode = get_provider_code(rechargeTransaction.operatorId)
5158
    if rechargeTransaction.deviceType == 1:
5159
        rtype = 'MTP'
5160
    else:
5161
        rtype = 'RCH'
7669 rajveer 5162
    retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(rechargeTransaction.id, rtype, strProviderCode, rechargeTransaction.deviceNum, rechargeTransaction.amount, rechargeTransaction.plan, store.hotspotId)
7075 rajveer 5163
    rechargeTransaction.spiceTID = spiceTID
7369 rajveer 5164
    rechargeTransaction.aggTID = aggTID
5165
    rechargeTransaction.providerTID = providerTID
7075 rajveer 5166
    rechargeTransaction.responseTime = datetime.datetime.now()
5167
    rechargeTransaction.description = description
5168
    if retCode == '00' and retStatus == 'S':
5169
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
7096 anupam.sin 5170
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
7075 rajveer 5171
 
5172
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
5173
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_UNKNOWN
5174
    else:
5175
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_FAILED
5176
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
5177
            rechargeTransaction.description = "Invalid Amount"
5178
        elif retCode in ('ECL', 'SVECL', 'SCL'):
5179
            rechargeTransaction.description = "Customer Exceeded Daily Limit"
5180
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
5181
            rechargeTransaction.description = "Invalid Device Number"
5182
 
5183
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
5184
        wallet = WalletForCompany.get_by(companyId=store.companyId)
5185
        wh = WalletHistoryForCompany()
5186
        wh.walletId = wallet.id
5187
        wh.amount = rechargeTransaction.amount
5188
        wh.transactionTime = rechargeTransaction.responseTime
5189
        wh.openingBal = wallet.amount
5190
        wh.closingBal = wallet.amount + wh.amount
5191
        wh.referenceNumber = rechargeTransaction.id 
5192
        wh.description = "Credited amount"
5193
 
5194
        wallet.amount = wallet.amount + rechargeTransaction.amount
5195
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
7076 rajveer 5196
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
7075 rajveer 5197
 
5198
    session.commit()
5199
 
7073 anupam.sin 5200
    return rechargeTransaction
5201
 
7080 anupam.sin 5202
def get_frcs(circleId, operatorId):
7267 anupam.sin 5203
    query = FRC.query.filter(FRC.circleId == circleId)
5204
    if(operatorId > 0):
5205
        query = query.filter(FRC.operatorId == operatorId)
5206
 
5207
    frcs = query.all()
5208
 
7096 anupam.sin 5209
    if frcs is None:
5210
        return []
5211
    return frcs
7080 anupam.sin 5212
 
5213
def get_recharge_transaction(rechargeId):
5214
    recharge = RechargeTransaction.get_by(id = rechargeId)
5215
    if not recharge:
5216
        raise TransactionServiceException(108, "no such transaction")
5217
    return recharge
5218
 
7096 anupam.sin 5219
def get_hotspot_store(id, hotspotid):
5220
    store = None
5221
    if id > 0:
5222
        store = HotspotStore.query.filter(HotspotStore.id == id).first()
5223
    elif len(hotspotid) > 0:
5224
        store = HotspotStore.query.filter(HotspotStore.hotspotId == hotspotid).first()
5225
    else:
5226
        raise TransactionServiceException(119, 'No such store')
5227
    if store:
5228
        return store
5229
    else:
5230
        raise TransactionServiceException(119, 'No such store')
5231
 
5232
def get_circle(id, code):
5233
    circle = None
5234
    if id > 0:
5235
        circle = TelecomCircle.get_by(id = id)
5236
    elif len(code) > 0:
5237
        circle = TelecomCircle.get_by(code = code)
5238
    else:
5239
        raise TransactionServiceException(119, 'No such circle')
5240
    if circle:
5241
        return circle
5242
    else:
5243
        raise TransactionServiceException(119, 'No such circle')
5244
 
7109 anupam.sin 5245
def retrieve_hotspot_recharge_invoice(id):
5246
    recharge = RechargeTransaction.get_by(id = id)
7139 amit.gupta 5247
    filename = "/tmp/recharge" + str(recharge.invoiceNumber) + ".pdf"
7109 anupam.sin 5248
    operator = ServiceProvider.get_by(id = recharge.operatorId).name
5249
    amount = recharge.amount
5250
    telNum = "+91 " + str(recharge.deviceNum)
5251
    customerName = recharge.name
5252
    invNum = str(recharge.invoiceNumber)
5253
    billingTime = recharge.responseTime
7151 amit.gupta 5254
    payMethod = recharge.payMethod
5255
    return __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod)
7109 anupam.sin 5256
 
7190 amar.kumar 5257
def split_freebie_order(order_id, splitReason, shippingDate):
5258
    order = get_order(order_id)
5259
    freebie_order = Order()
5260
 
5261
    freebie_order.transaction = order.transaction
5262
 
5263
    freebie_order.customer_id = order.customer_id
5264
    freebie_order.customer_email = order.customer_email
5265
    freebie_order.customer_name = order.customer_name
5266
    freebie_order.customer_pincode = order.customer_pincode
5267
    freebie_order.customer_address1 = order.customer_address1
5268
    freebie_order.customer_address2 = order.customer_address2
5269
    freebie_order.customer_city = order.customer_city
5270
    freebie_order.customer_state = order.customer_state
5271
    freebie_order.customer_mobilenumber = order.customer_mobilenumber
5272
    freebie_order.total_weight = order.total_weight
5273
    freebie_order.total_amount = 0.01
5274
    freebie_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
5275
    freebie_order.statusDescription = "In Process";
5276
    freebie_order.created_timestamp = datetime.datetime.now()
5277
    freebie_order.cod = 0
5278
    freebie_order.orderType = OrderType.B2C
5279
    freebie_order.pickupStoreId = 0
5280
    freebie_order.otg = 0
5281
    freebie_order.insurer = 0
5282
    freebie_order.insuranceAmount = 0
7564 rajveer 5283
    freebie_order.source = order.source
7190 amar.kumar 5284
 
5285
    logistics_client = LogisticsClient().get_client()
5286
    logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, 1, DeliveryType.PREPAID, PickUpType.COURIER)
5287
    freebie_order.logistics_provider_id = logistics_info.providerId;
5288
    freebie_order.tracking_id = logistics_info.airway_billno
5289
    freebie_order.airwaybill_no = logistics_info.airway_billno
5290
    freebie_order.expected_delivery_time = (to_py_date(shippingDate)+datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)  
5291
    freebie_order.promised_delivery_time = order.promised_delivery_time
5292
    freebie_order.expected_shipping_time = to_py_date(shippingDate)
5293
    freebie_order.promised_shipping_time = order.promised_shipping_time
5294
 
5295
    inventory_client = InventoryClient().get_client()
7198 amar.kumar 5296
    item_availability = inventory_client.getItemAvailabilityAtLocation(order.freebieItemId,1)
7190 amar.kumar 5297
    freebie_order.warehouse_id = item_availability[2]
7303 amar.kumar 5298
    freebie_order.fulfilmentWarehouseId = item_availability[0]
7190 amar.kumar 5299
 
5300
    catalog_client = CatalogClient().get_client()
5301
    item = catalog_client.getItem(order.freebieItemId)
5302
    freebie_order.total_weight = item.weight
5303
 
5304
    litem = LineItem()
5305
    litem.item_id = item.id
5306
    litem.productGroup = item.productGroup
5307
    litem.brand = item.brand
5308
    litem.model_number = item.modelNumber
5309
    litem.model_name = item.modelName
5310
    litem.color = item.color
5311
    litem.extra_info = "Freebie Order for Order ID " + str(order.id)
5312
    litem.quantity = 1
5313
    litem.unit_price = 0.01
5314
    litem.unit_weight = item.weight
5315
    litem.total_price = 0.01
5316
    litem.total_weight = item.weight
5317
    litem.vatRate = 5.0
5318
 
5319
    freebie_order.lineitems.append(litem)
7198 amar.kumar 5320
    order.freebieItemId = 0
7190 amar.kumar 5321
    session.commit()
7198 amar.kumar 5322
    order.lineitems[0].extra_info = "Parent Order for Order ID " + str(freebie_order.id)
7190 amar.kumar 5323
 
7198 amar.kumar 5324
    inventory_client = InventoryClient().get_client()   
5325
    inventory_client.reserveItemInWarehouse(freebie_order.lineitems[0].item_id, item_availability[0], sourceId, freebie_order.id, to_java_date(freebie_order.created_timestamp), to_java_date(freebie_order.promised_shipping_time), 1)
7190 amar.kumar 5326
    parentOrderAttribute = Attribute()
5327
    parentOrderAttribute.orderId = freebie_order.id
5328
    parentOrderAttribute.name = "parentOrderIdForFreebie"
5329
    parentOrderAttribute.value = str(order.id)
5330
 
5331
    freebieOrderAttribute = Attribute()
5332
    freebieOrderAttribute.orderId = order.id
5333
    freebieOrderAttribute.name = "freebieOrderId"
5334
    freebieOrderAttribute.value = str(freebie_order.id)
5335
    session.commit()
5336
 
7198 amar.kumar 5337
    return to_t_order(freebie_order)
7190 amar.kumar 5338
 
7151 amit.gupta 5339
def __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod): 
7109 anupam.sin 5340
    PAGE_HEIGHT=defaultPageSize[1];
5341
    styles = getSampleStyleSheet()
5342
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
5343
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
5344
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
5345
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
7096 anupam.sin 5346
 
7109 anupam.sin 5347
    Story = []
5348
    prologueStyle = styles["prologue"]
5349
    lineStyle = styles["line"]
5350
    textStyle = styles["text"]
5351
    epilogueStyle = styles["epilogue"]
7096 anupam.sin 5352
 
7109 anupam.sin 5353
    doc = BaseDocTemplate(filename,showBoundary=0)
5354
 
5355
    #Two Columns
5356
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
5357
 
5358
 
5359
 
5360
    Story.append(Paragraph("""Spice Retail Limited<br></br>
5361
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
5362
        2,Kalkaji Industrial Area,New Delhi<br></br>
5363
          .<br></br>
5364
        TIN NO. 07430284979<br></br>
5365
        Service Tax No:AAACM0294PST001<br></br><br></br><br></br>""", prologueStyle))
5366
    drawLine(Story, lineStyle)
5367
 
5368
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
5369
    drawLine(Story, lineStyle)
5370
 
5371
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
5372
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
7151 amit.gupta 5373
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("PAYMENT MODE:", PayMethod._VALUES_TO_NAMES[payMethod]).replace(" ", "&nbsp;"), textStyle))
7109 anupam.sin 5374
    drawLine(Story, lineStyle)
5375
 
5376
    Story.append(Paragraph(('{0:<16s}{1:>13s}{2:11.2f}').format(operator, "RECHARGE", amount).replace(' ', '&nbsp;'),textStyle))
5377
    drawLine(Story, lineStyle)
5378
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
5379
 
5380
    #start the construction of the pdf
5381
    doc.build(Story)
5382
 
5383
    try:
5384
        fileToSend = open(filename, "rb")
5385
        pdfFile = fileToSend.read()
5386
    except:
5387
        return bin(0)
5388
 
5389
    return pdfFile
5390
 
7172 anupam.sin 5391
def get_recharge_transactions_by_number(number, storeId):
7169 anupam.sin 5392
    query = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == number)
7172 anupam.sin 5393
    query = query.filter(RechargeTransaction.storeId == storeId)
7169 anupam.sin 5394
    return query.all()
5395
 
5396
def update_hotspot_store_password(storeId, password):
5397
    store = None
5398
    if password is None:
5399
        return False
5400
    if storeId:
5401
        store = HotspotStore.query.filter(HotspotStore.id == storeId).first()
5402
    if store:
5403
        store.password = password
5404
        session.commit()
5405
        return True
5406
    return False
5407
 
7263 anupam.sin 5408
def get_source_detail(source):
5409
    detail = SourceDetail.get_by(id=source)
5410
    if not detail:
5411
        raise TransactionServiceException(108, "no such source")
5412
    return detail
5413
 
7267 anupam.sin 5414
def get_all_circles():
5415
    circles = TelecomCircle.query.all();
5416
    if not circles:
5417
        circles = []
5418
    return circles 
5419
 
5420
def delete_frcs(frcIdsToDelete):
5421
    toReturn = False
5422
    if frcIdsToDelete:
5423
        for frcId in frcIdsToDelete:
5424
            frc = FRC.get_by(id = frcId)
5425
            if frc:
5426
                frc.delete()
5427
                toReturn = True
5428
        session.commit()
5429
        return toReturn
5430
    else:
5431
        return toReturn
5432
 
7285 rajveer 5433
def topup_company_wallet(companyId, amount):
5434
    wallet = WalletForCompany.query.filter(WalletForCompany.id == companyId).with_lockmode("update").one()
5435
    company = Company.get_by(id = companyId)
5436
    wh = WalletHistoryForCompany()
5437
    wh.walletId = wallet.id
5438
    wh.openingBal = wallet.amount
5439
    wh.closingBal = wallet.amount +  amount
5440
    wh.amount = amount
5441
    wh.transactionTime = datetime.datetime.now()
5442
    wh.referenceNumber =  get_next_invoice_number(OrderType.WALLETCREDIT)
5443
    wh.description = "Wallet Credited"
5444
 
5445
    wallet.amount += amount
5446
    session.commit()
5447
    mail("cnc.center@shop2020.in", "5h0p2o2o", ["rajveer.singh@shop2020.in", "anupam.singh@shop2020.in", "Ashwani.Kumar@spiceretail.co.in","parveen.mittal@spiceretail.co.in","pardeep.panwar@spiceretail.co.in","gagan.sharma@spiceretail.co.in","j.p.gupta@shop2020.in", "rajneesh.arora@shop2020.in", "amit.tyagi@spiceretail.co.in"] , company.name + " wallet topped up by " +  str(amount) + " rupees.", "", [], [], [])
5448
    return wallet.amount
7267 anupam.sin 5449
 
7285 rajveer 5450
def get_wallet_balance_for_company(companyId):
5451
    return WalletForCompany.get_by(companyId = companyId).amount
5452
 
7311 kshitij.so 5453
def add_amazon_order(amazonOrder):
5454
    amazon_order = AmazonOrder()
5455
    amazon_order.orderId = amazonOrder.orderId
5456
    amazon_order.amazonOrderCode = amazonOrder.amazonOrderCode
5457
    amazon_order.amazonOrderItemCode = amazonOrder.amazonOrderItemCode
5458
    amazon_order.transactionId = amazonOrder.transactionId
5459
    amazon_order.item_id= amazonOrder.item_id
5460
    amazon_order.status= amazonOrder.status
7715 vikram.rag 5461
    amazon_order.purchaseDateOnAmazon= to_py_date(amazonOrder.purchaseDateOnAmazon);
7311 kshitij.so 5462
    session.commit()
5463
 
7322 vikram.rag 5464
def update_amazon_order_status(order_id,status):
7577 rajveer 5465
    row = AmazonOrder.get_by(orderId=order_id)
5466
    row.status=status
5467
    session.commit()
5468
    return True
7311 kshitij.so 5469
 
5470
def get_amazon_orders_marked_sent():
7683 vikram.rag 5471
    return AmazonOrder.query.filter(AmazonOrder.status=='Order-Payment-Success').all()
7311 kshitij.so 5472
 
7683 vikram.rag 5473
def get_amazon_orders_shipped():
7311 kshitij.so 5474
    amazonShippedOrders = []
7683 vikram.rag 5475
    ###toDate = datetime.datetime.now()
5476
    ###fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
7311 kshitij.so 5477
    orders = get_amazon_orders_marked_sent()
7694 vikram.rag 5478
    if not orders:
5479
        return amazonShippedOrders
5480
 
7311 kshitij.so 5481
    for order in orders:
7694 vikram.rag 5482
        row = Order.query.filter(Order.id == order.orderId).first()
5483
        if row.shipping_timestamp:
7683 vikram.rag 5484
            amazonShippedOrders.append(to_t_order(row))
7311 kshitij.so 5485
    return amazonShippedOrders
5486
 
5487
def get_amazon_orders_cancelled(interval):
5488
    amazonCancelledOrders = []
5489
    toDate = datetime.datetime.now()
5490
    fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
5491
    orders = get_amazon_orders_marked_sent()
5492
    for order in orders:
5493
        row = Order.query.filter(Order.refund_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()
7314 kshitij.so 5494
        if row is None:
5495
            continue
7311 kshitij.so 5496
        if ( row.status == 15 or row.status == 18 or row.status == 34 ):
5497
            amazonCancelledOrders.append(to_t_order(row))
5498
    return amazonCancelledOrders        
7322 vikram.rag 5499
 
5500
def get_amazon_order(order_id):
5501
    return AmazonOrder.get_by(orderId=order_id)
5502
 
7542 vikram.rag 5503
def get_amazon_order_by_amazonorderid(amazonOrderId):
5504
    return AmazonOrder.query.filter(AmazonOrder.amazonOrderCode==amazonOrderId)
5505
 
5506
 
7442 vikram.rag 5507
def get_amazon_orders_to_acknowledge():
5508
    orderstatus = []
5509
    orderstatus.append('Order-Payment-Success')
5510
    orderstatus.append('Order-Payment-Failure')
5511
    return session.query(AmazonOrder.amazonOrderCode,AmazonOrder.amazonOrderItemCode,AmazonOrder.status,AmazonOrder.transactionId,func.count(AmazonOrder.orderId)).filter(AmazonOrder.status.in_(orderstatus)).group_by(AmazonOrder.amazonOrderItemCode,AmazonOrder.status).all()
5512
 
5513
def change_amazon_order_status(amazonOrderCode,status):
5514
    for order in AmazonOrder.query.filter(AmazonOrder.amazonOrderCode==amazonOrderCode):
5515
        order.status = status
5516
    session.commit()   
7311 kshitij.so 5517
 
7343 anupam.sin 5518
def get_orders_for_store(orderId, storeId, startDate, endDate, statuses):
5519
    orders = []
5520
    query = Order.query
5521
    if storeId < 1:
5522
        return orders
5523
    elif orderId > 0:
5524
        query = query.filter(Order.id == orderId)
5525
    else :
5526
        if startDate:
5527
            query = query.filter(cast(Order.created_timestamp, DATE) >= startDate.date())
5528
 
5529
        if endDate:
5530
            query = query.filter(cast(Order.created_timestamp, DATE) <= endDate.date())
5531
 
5532
        if len(statuses) > 0:
5533
            query = query.filter(Order.status.in_(statuses))
5534
 
5535
    orders = query.filter(Order.storeId == storeId).all()
5536
    return orders
5537
 
7386 anupam.sin 5538
def get_store_order_advance_invoice(orderId, storeId):
7343 anupam.sin 5539
    order = Order.get_by(id = orderId)
7386 anupam.sin 5540
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
7402 anupam.sin 5541
    store = HotspotStore.get_by(id = storeId)
7399 anupam.sin 5542
 
7346 anupam.sin 5543
    modelName = "&nbsp;"
5544
    modelNumber = "&nbsp;"
5545
    color = "&nbsp;"
5546
    if order.lineitems[0].model_name:
5547
        modelName = modelName + order.lineitems[0].model_name
5548
    if order.lineitems[0].model_number:
5549
        modelNumber = modelNumber + order.lineitems[0].model_number
5550
    if order.lineitems[0].color:
5551
        color = color + order.lineitems[0].color
5552
 
5553
    product = order.lineitems[0].brand +  modelName + modelNumber + color
7386 anupam.sin 5554
    advanceAmount = order.advanceAmount
7343 anupam.sin 5555
    totalAmount = order.total_amount
7346 anupam.sin 5556
    delivery = order.expected_delivery_time
7386 anupam.sin 5557
 
7343 anupam.sin 5558
    customerName = order.customer_name
7386 anupam.sin 5559
    customerAdd1 = order.customer_address1
5560
    customerAdd2 = order.customer_address2
5561
    customerCity = order.customer_city
5562
    customerState = order.customer_state
5563
    customerMobile = order.customer_mobilenumber
5564
    customerPin = order.customer_pincode
7393 anupam.sin 5565
    inCash = storeOrderDetail.cashAmount
5566
    byCard = storeOrderDetail.cardAmount
7399 anupam.sin 5567
 
7400 anupam.sin 5568
    if order.status in (15, 34) and (storeOrderDetail.cashRefundAmount > 0 or storeOrderDetail.cashRefundAmount > 0):
7399 anupam.sin 5569
        filename = "/tmp/order-refund-" + str(order.id) + ".pdf"
5570
        inCash = storeOrderDetail.cashRefundAmount
5571
        byCard = storeOrderDetail.cardRefundAmount
7402 anupam.sin 5572
        return __printStoreOrderCancellationReceipt(store, order.id, filename, customerName, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, product, advanceAmount,inCash, byCard, order.created_timestamp.date(), order.refund_timestamp.date())
7399 anupam.sin 5573
    else:
5574
        filename = "/tmp/order-" + str(order.id) + ".pdf"
7343 anupam.sin 5575
    #payMethod = recharge.payMethod
7386 anupam.sin 5576
#    if order.status == 15 or order.status == 34:
5577
#        return __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, mode, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin)
7427 anupam.sin 5578
    return __printStoreOrderAdvanceInvoice(store, order.id, filename, product, advanceAmount, totalAmount, customerName, delivery, inCash, byCard, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, order.created_timestamp.date())
7343 anupam.sin 5579
 
7402 anupam.sin 5580
def __printStoreOrderCancellationReceipt(store, orderId, filename, customerName, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, product, advanceAmount,inCash, byCard, createdDate, cancelDate): 
7399 anupam.sin 5581
    PAGE_HEIGHT=defaultPageSize[1];
5582
    styles = getSampleStyleSheet()
5583
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
5584
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
5585
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
5586
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
5587
 
5588
    Story = []
5589
    prologueStyle = styles["prologue"]
5590
    lineStyle = styles["line"]
5591
    textStyle = styles["text"]
5592
    epilogueStyle = styles["epilogue"]
7343 anupam.sin 5593
 
7399 anupam.sin 5594
    doc = BaseDocTemplate(filename,showBoundary=0)
5595
 
5596
    #Two Columns
5597
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
5598
 
5599
 
7402 anupam.sin 5600
    Story.append(Paragraph(store.line1, prologueStyle))
5601
    Story.append(Paragraph(store.line2 + ', ' + store.city, prologueStyle))
5602
    Story.append(Paragraph(store.state + ' - ' + store.pin, prologueStyle))
7399 anupam.sin 5603
 
5604
    drawLine(Story, lineStyle)
5605
 
7427 anupam.sin 5606
    Story.append(Paragraph("{0:^39s}".format("*** ADVANCE REFUND RECEIPT ***").replace(" ", "&nbsp;"), textStyle))
7399 anupam.sin 5607
 
5608
    drawLine(Story, lineStyle)
5609
 
5610
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
5611
    Story.append(Paragraph("{0:<10s}{1:<29s}".format("MOBILE:", customerMobile).replace(" ", "&nbsp;"), textStyle))
5612
    Story.append(Paragraph("{0:<10s}{1:<29s}".format("ORDER ID:", str(orderId)).replace(" ", "&nbsp;"), textStyle))
7547 anupam.sin 5613
    Story.append(Paragraph("{0:<20s}{1:  %d/%m/%Y}".format("CURRENT DATE:", datetime.datetime.now().date()).replace(" ", "&nbsp;"), textStyle))
7399 anupam.sin 5614
    Story.append(Paragraph("{0:<20s}{1:  %d/%m/%Y}".format("ORDER DATE:", createdDate).replace(" ", "&nbsp;"), textStyle))
7402 anupam.sin 5615
    Story.append(Paragraph("{0:<20s}{1:  %d/%m/%Y}".format("CANCELLATION DATE:", cancelDate).replace(" ", "&nbsp;"), textStyle))
7399 anupam.sin 5616
 
5617
    drawLine(Story, lineStyle)
5618
 
5619
    Story.append(Paragraph("{0:^39s}".format("DELIVERY ADDRESS").replace(" ", "&nbsp;"), textStyle))
5620
 
5621
    drawLine(Story, lineStyle)
5622
 
5623
    Story.append(Paragraph(customerAdd1, textStyle))
5624
    if len(customerAdd2) > 0:
5625
        Story.append(Paragraph(customerAdd2, textStyle))
5626
    Story.append(Paragraph(customerCity, textStyle))
5627
    Story.append(Paragraph(customerState + " - " + customerPin, textStyle))
5628
 
5629
    drawLine(Story, lineStyle)
5630
 
5631
    Story.append(Paragraph("{0:^39s}".format("PRODUCT NAME").replace(" ", "&nbsp;"), textStyle))
5632
 
5633
    drawLine(Story, lineStyle)
5634
 
5635
    Story.append(Paragraph(product, textStyle))
5636
 
5637
    drawLine(Story, lineStyle)
5638
 
5639
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("ADVANCE AMOUNT: ", advanceAmount).replace(' ', '&nbsp;'),textStyle))
5640
    Story.append(Paragraph(('{0:<30s}{1:>9.2f}').format("LESS-CANCELLATION CHARGES: ", advanceAmount-inCash-byCard).replace(' ', '&nbsp;'),textStyle))
5641
    Story.append(Paragraph(('{0:<30s}{1:>9.2f}').format("AMOUNT TO BE REFUNDED: ", inCash+byCard).replace(' ', '&nbsp;'),textStyle))
5642
    if inCash > 0:
7427 anupam.sin 5643
        Story.append(Paragraph(('{0:>20s}{1:>19.2f}').format("REFUND IN CASH: ", inCash).replace(' ', '&nbsp;'),textStyle))
7399 anupam.sin 5644
    if byCard > 0:
7427 anupam.sin 5645
        Story.append(Paragraph(('{0:>20s}{1:>19.2f}').format("REFUND BY CARD: ", byCard).replace(' ', '&nbsp;'),textStyle))
7399 anupam.sin 5646
 
5647
    drawLine(Story, lineStyle)
5648
 
5649
    Story.append(Paragraph("CUSTOMER SIGNATURE :", textStyle))
5650
    Story.append(Paragraph("&nbsp;", textStyle))
5651
 
5652
    drawLine(Story, lineStyle)
5653
 
5654
    drawLine(Story, lineStyle)
5655
 
7547 anupam.sin 5656
    Story.append(Paragraph("Terms & Conditions:", textStyle))                                        
7427 anupam.sin 5657
    Story.append(Paragraph("* Original copy of 'Advance Receipt' Shall be provided  by Customer to get the refund",textStyle))
5658
    Story.append(Paragraph("* All disputes subject to Delhi jusrisdiction",textStyle))                                        
7399 anupam.sin 5659
 
5660
    drawLine(Story, lineStyle)
5661
 
5662
    Story.append(Paragraph(('{0:<20s}{1:>19s}').format("Customer care : ", "0120-6744700").replace(' ', '&nbsp;'),textStyle))
5663
 
5664
    drawLine(Story, lineStyle)
5665
 
5666
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
5667
    #start the construction of the pdf
5668
    doc.build(Story)
5669
    try:
5670
        fileToSend = open(filename, "rb")
5671
        pdfFile = fileToSend.read()
5672
    except:
5673
        return bin(0)
5674
 
5675
    return pdfFile
5676
 
5677
 
5678
 
5679
 
7427 anupam.sin 5680
def __printStoreOrderAdvanceInvoice(store, orderId, filename, product, advanceAmount, totalAmount, customerName, delivery, inCash, byCard, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, createdDate): 
7343 anupam.sin 5681
    PAGE_HEIGHT=defaultPageSize[1];
5682
    styles = getSampleStyleSheet()
5683
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
5684
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
5685
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
5686
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
5687
 
5688
    Story = []
5689
    prologueStyle = styles["prologue"]
5690
    lineStyle = styles["line"]
5691
    textStyle = styles["text"]
5692
    epilogueStyle = styles["epilogue"]
5693
 
5694
    doc = BaseDocTemplate(filename,showBoundary=0)
5695
 
5696
    #Two Columns
5697
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
5698
 
5699
 
7402 anupam.sin 5700
    Story.append(Paragraph(store.line1, prologueStyle))
5701
    Story.append(Paragraph(store.line2 + ', ' + store.city, prologueStyle))
5702
    Story.append(Paragraph(store.state + ' - ' + store.pin, prologueStyle))
7386 anupam.sin 5703
 
7402 anupam.sin 5704
 
7343 anupam.sin 5705
    drawLine(Story, lineStyle)
7393 anupam.sin 5706
    Story.append(Paragraph("{0:^39s}".format("*** ADVANCE RECEIPT ***").replace(" ", "&nbsp;"), textStyle))
5707
    drawLine(Story, lineStyle)
7343 anupam.sin 5708
 
7386 anupam.sin 5709
    Story.append(Paragraph("{0:^39s}".format("DELIVERY ADDRESS").replace(" ", "&nbsp;"), textStyle))
5710
    drawLine(Story, lineStyle)
5711
    Story.append(Paragraph(customerAdd1, textStyle))
5712
    if len(customerAdd2) > 0:
5713
        Story.append(Paragraph(customerAdd2, textStyle))
5714
 
5715
    Story.append(Paragraph(customerCity, textStyle))
5716
    Story.append(Paragraph(customerState + " - " + customerPin, textStyle))
5717
    drawLine(Story, lineStyle)
7343 anupam.sin 5718
 
5719
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
7386 anupam.sin 5720
    Story.append(Paragraph("{0:<10s}{1:<29s}".format("MOBILE:", customerMobile).replace(" ", "&nbsp;"), textStyle))
7427 anupam.sin 5721
    Story.append(Paragraph("{0:<10s}{1:<12s}{2:7s}{3:  %d/%m/%Y}".format("ORDER ID:", str(orderId), "DATE:", createdDate).replace(" ", "&nbsp;"), textStyle))
7547 anupam.sin 5722
    Story.append(Paragraph("{0:<20s}{1:  %d/%m/%Y}".format("CURRENT DATE:", datetime.datetime.now().date()).replace(" ", "&nbsp;"), textStyle))
7393 anupam.sin 5723
    Story.append(Paragraph("{0:<20s}{1:  %d/%m/%Y}".format("EXPECTED DELIVERY:", delivery).replace(" ", "&nbsp;"), textStyle))
7343 anupam.sin 5724
 
5725
    drawLine(Story, lineStyle)
7346 anupam.sin 5726
    Story.append(Paragraph("{0:^39s}".format("PRODUCT NAME").replace(" ", "&nbsp;"), textStyle))
7343 anupam.sin 5727
    drawLine(Story, lineStyle)
5728
    Story.append(Paragraph("{0:<39s}".format(product).replace(" ", "&nbsp;"), textStyle))
5729
    drawLine(Story, lineStyle)
5730
 
5731
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("TOTAL PRICE: ", totalAmount).replace(' ', '&nbsp;'),textStyle))
7386 anupam.sin 5732
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("ADVANCE AMOUNT: ", advanceAmount).replace(' ', '&nbsp;'),textStyle))
7399 anupam.sin 5733
    if inCash > 0:
7427 anupam.sin 5734
        Story.append(Paragraph(('{0:>13s}{1:>26.2f}').format("IN CASH: ", inCash).replace(' ', '&nbsp;'),textStyle))
7399 anupam.sin 5735
    if byCard > 0:
7427 anupam.sin 5736
        Story.append(Paragraph(('{0:>13s}{1:>26.2f}').format("BY CARD: ", byCard).replace(' ', '&nbsp;'),textStyle))
7386 anupam.sin 5737
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("BALANCE TO BE PAID: ", (totalAmount - advanceAmount)).replace(' ', '&nbsp;'),textStyle))
7343 anupam.sin 5738
 
5739
    drawLine(Story, lineStyle)
7547 anupam.sin 5740
    Story.append(Paragraph("Terms & Conditions:", textStyle))                                        
7427 anupam.sin 5741
    Story.append(Paragraph("* In case of cancellation of order on customer request, 10% of product amount subject to minimum Rs 500/- shall be deducted as cancellation charges. Customer shall provide original copy of 'Advance Receipt' to get the balance amount as refund",textStyle))                                        
7386 anupam.sin 5742
    Story.append(Paragraph("* Balance amount as mentioned above to be paid at the time of delivery of product to courier agency. Refusal to accept the product delivered through courier shall be deemed as cancellation of order and cancellation charges shall become applicable.",textStyle))                                         
7427 anupam.sin 5743
    Story.append(Paragraph("* The product as mentioned above shall be made available to the customer, subject to its availability from the manufacturer",textStyle))
5744
    Story.append(Paragraph("* All disputes subject to Delhi Jurisdiction",textStyle))                                        
7393 anupam.sin 5745
    drawLine(Story, lineStyle)
5746
    Story.append(Paragraph(('{0:<20s}{1:>19s}').format("Customer care : ", "0120-6744700").replace(' ', '&nbsp;'),textStyle))
5747
    drawLine(Story, lineStyle)
7386 anupam.sin 5748
 
7343 anupam.sin 5749
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
5750
 
5751
    #start the construction of the pdf
5752
    doc.build(Story)
5753
 
5754
    try:
5755
        fileToSend = open(filename, "rb")
5756
        pdfFile = fileToSend.read()
5757
    except:
5758
        return bin(0)
5759
 
5760
    return pdfFile
5761
 
7370 anupam.sin 5762
def add_frc(circle, operatorId, denomination, maxDiscount):
7371 anupam.sin 5763
    frc = FRC.query.filter(FRC.circleId == circle).filter(FRC.operatorId == operatorId).filter(FRC.denomination == denomination).first()
7370 anupam.sin 5764
    if frc:
5765
        frc.maxDiscount = maxDiscount
5766
    else:
5767
        frc = FRC()
5768
        frc.circleId = circle
5769
        frc.denomination = denomination
5770
        frc.maxDiscount = maxDiscount
5771
        frc.operatorId = operatorId
5772
    session.commit()
5773
    return True 
5774
 
7371 anupam.sin 5775
def add_series(circle, operatorId, series):
5776
    operatorSeriesObject = OperatorSeries.query.filter(OperatorSeries.series == series).first()
5777
    if operatorSeriesObject:
5778
        circleName = TelecomCircle.get_by(id = operatorSeriesObject.circleId).name
5779
        operatorName = ServiceProvider.get_by(id = operatorSeriesObject.operatorId).name
5780
        return "Series already exists for : " + operatorName + " in circle : " + circleName
5781
    else :
5782
        operatorSeriesObject = OperatorSeries()
5783
        operatorSeriesObject.series = series
5784
        operatorSeriesObject.circleId = circle
5785
        operatorSeriesObject.operatorId = operatorId
5786
        session.commit()
5787
        return "Successfully saved"
7386 anupam.sin 5788
 
5789
 
5790
def save_store_order_detail(thrift_storeOrderDetail):
5791
    txnId = thrift_storeOrderDetail.orderId
5792
    txn = Transaction.get_by(id=txnId)
5793
    oid = txn.orders[0].id
5794
    ds_storeOrderDetail = StoreOrderDetail()
5795
    ds_storeOrderDetail.orderId = oid
5796
    ds_storeOrderDetail.advanceAmount = thrift_storeOrderDetail.advanceAmount
5797
    ds_storeOrderDetail.cardAmount = thrift_storeOrderDetail.cardAmount
5798
    ds_storeOrderDetail.cashAmount = thrift_storeOrderDetail.cashAmount
5799
    ds_storeOrderDetail.storeId = thrift_storeOrderDetail.storeId
5800
    ds_storeOrderDetail.payStatus = thrift_storeOrderDetail.payStatus
7399 anupam.sin 5801
    ds_storeOrderDetail.cardRefundAmount = thrift_storeOrderDetail.cardRefundAmount
5802
    ds_storeOrderDetail.cashRefundAmount = thrift_storeOrderDetail.cashRefundAmount
5803
    ds_storeOrderDetail.edcBank = thrift_storeOrderDetail.edcBank
7423 anupam.sin 5804
    ds_storeOrderDetail.approvalCode = thrift_storeOrderDetail.approvalCode
7611 anupam.sin 5805
    ds_storeOrderDetail.cardType = thrift_storeOrderDetail.cardType
7386 anupam.sin 5806
    session.commit()
5807
    return True
5808
 
5809
def get_store_order_detail(orderId, storeId):
5810
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
5811
    if storeOrderDetail:
5812
        return storeOrderDetail
5813
    else:
5814
        return StoreOrderDetail()
5815
 
5816
def get_all_edc_banks():
5817
    allBankNames = []
5818
    edcBanks = EdcBank.query.all();
5819
    for bank in edcBanks:
5820
        allBankNames.append(bank.name)
5821
    return allBankNames
7393 anupam.sin 5822
 
5823
def save_refund_amounts_for_store_order(orderId, storeId, cashRefundAmount, cardRefundAmount):
5824
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
5825
    if storeOrderDetail:
5826
        storeOrderDetail.cashRefundAmount = cashRefundAmount
5827
        storeOrderDetail.cardRefundAmount = cardRefundAmount
5828
        session.commit()
5829
        return True
5830
    else:
5831
        return False
7427 anupam.sin 5832
 
5833
def get_collections_for_store(storeId, startdate, enddate):
5834
    if startdate == -1:
5835
        startdate = None
5836
    if enddate == -1:
5837
        enddate = None
5838
    if storeId== 0:
5839
        storeId = None
5840
 
5841
    if storeId:
5842
        store = HotspotStore.get_by(id = storeId)
5843
 
5844
    hotspotId = store.hotspotId
5845
 
5846
    query = StoreOrderCollection.query
5847
    if storeId is not None:
5848
        query = query.filter(StoreOrderCollection.hotspotId == hotspotId)
5849
    else:
5850
        return []
5851
 
5852
    if startdate is not None and enddate is not None:
5853
        startdate = to_py_date(startdate).date()
5854
        enddate = to_py_date(enddate).date()
5855
        if startdate == enddate:
5856
            query = query.filter(cast(StoreOrderCollection.pushedAt, DATE) == enddate)
5857
        elif enddate < startdate:
5858
            query = query.filter(between(cast(StoreOrderCollection.pushedAt, DATE), enddate, startdate))
5859
        else:
5860
            query = query.filter(between(cast(StoreOrderCollection.pushedAt, DATE), startdate, enddate))
5861
    elif startdate is not None:
5862
        startdate = to_py_date(startdate).date()
5863
        query = query.filter(cast(StoreOrderCollection.pushedAt, DATE) >= startdate)
5864
    elif enddate is not None:
5865
        enddate = to_py_date(enddate).date()
5866
        query = query.filter(cast(StoreOrderCollection.pushedAt, DATE) <= enddate)
5867
 
5868
    return query.filter(StoreOrderCollection.pushedToOcr == 1).all()    
5869
 
7741 kshitij.so 5870
def update_timestamp_for_amazon_order(orderDeliveryMap):
7762 kshitij.so 5871
    for orderId,dateMap in orderDeliveryMap.iteritems():
7741 kshitij.so 5872
        order = get_order(orderId)
7762 kshitij.so 5873
        order.expected_delivery_time = datetime.datetime.strptime(dateMap.values()[0]+' 15:00:00', '%d-%m-%Y %H:%M:%S') 
5874
        order.promised_delivery_time = datetime.datetime.strptime(dateMap.values()[0]+' 15:00:00', '%d-%m-%Y %H:%M:%S')
5875
        promisedShipping = datetime.datetime.strptime(dateMap.keys()[0]+' 15:00:00', '%d-%m-%Y %H:%M:%S')
7741 kshitij.so 5876
        order.expected_shipping_time = promisedShipping
5877
        order.promised_shipping_time = promisedShipping
5878
        session.commit()
7460 kshitij.so 5879
    return True
7530 kshitij.so 5880
 
5881
def update_source_detail_timestamp(id,lastUpdatedOn):
5882
    detail = get_source_detail(id)
5883
    detail.lastUpdatedOn = to_py_date(lastUpdatedOn)
5884
    session.commit()
5885
    return True
7607 anupam.sin 5886
 
5887
def get_orders_by_mobile_number(mobileNumber):
5888
    return Order.query.filter(Order.customer_mobilenumber == mobileNumber).all()
5889
 
5890
def get_orders_by_amazon_id(amazonId):
5891
    orderIds = []
7645 anupam.sin 5892
    amazonOrders = AmazonOrder.query.filter(AmazonOrder.amazonOrderCode == amazonId).all()
7607 anupam.sin 5893
    for amazonOrder in amazonOrders:
5894
        orderIds.append(amazonOrder.orderId)
5895
    return get_order_list(orderIds)
7386 anupam.sin 5896
 
7822 amar.kumar 5897
def update_freebie_item(orderId, newFreebieItemId):
5898
    order = Order.get_by(id = orderId)
5899
    order.freebieItemId = newFreebieItemId
5900
    session.commit()
5901
    return order
7741 kshitij.so 5902
 
6915 anupam.sin 5903
if __name__ == '__main__':
7607 anupam.sin 5904
    print get_orders_by_mobile_number("9650889334")