Keep your facebook page updated using scheduling tools

facebook-thing-icon[Update 16.June.2012: Facebook has add post scheduling feature for page admin. Refer comment below by Victor Stanescu]

Running an engaging facebook page for a brand requires consistent postings and engagements (two way communications). While we can’t automate the interactivity part, but we can look into status/post scheduling tools to keep our page active. Below are two Facebook Post Scheduler that my company is using, we use it to plan and schedule our posts across the day and month. It helps us in planning and providing quality information to our followers and at the same time create a sound brand name for us. Here’s the tools.

 

1. Octopost

Octopost is the first tool we discovered and use to schedule our posts, it’s an facebook app where you can reach at https://apps.facebook.com/octopost/. Free version is available with 10 post limitation per month. While the unlimited version cost only USD 5 per month. On top of the familiar Facebook-like UI, we found its analytic part - “Engagement Insights” widget particularly useful to analyse and evaluate your post performance. This widget shows stats like "Total Responses – in like, comments etc” to your post.
Octopost went extra mile to help you with your finding content to post with the “Browse for Ideas”, such a great idea and convenient tool but hell, it’s a bad idea to use it! The content available in the directory are populated with international content and far not niche to engage our audience (unless you are running some sort of international news fan page). Kudos to Octopost for coming up with such a great tool and hope they can further improve in the “Browse for Ideas” widget and make it a unbeatable product.

 

2. Postcron

Postcron is another tool recommended by a friend of us. Like Octopost, it’s available Free with 10 post per month limitation. Their app can be found on http://postcron.com/. Their UI looks tidier and load faster as compare to Octopost. It also allows scheduling to twitter too . It has a good “Search Feature” which allow you to search through your post but it has an annoying “Time Zone Request” prompt. The app prompt for your time zone every time you login to the page which i feel quite annoying.
Feel free recommend your secret tools in the comment area. Happy facebook-ing!
Read More

Started a CSR project with a group of students – melaka3.com

Gullivers-Travels-icon Three months back, we started a project with a group of students. They were hired into the company to help setup and run a CSR (corporate social responsibility) project of my company – Melaka3.com

Melaka3.com is a brain child of these students and me, we were challenged to kick start a CSR project with limited funding (from my company) and technical support from the staffs. We came out with a few ideas and decided to go with Melaka3.com project because we think that it’s a sustainable and achievable project to run given our limited resources. So, what Melaka3.com is all about? and why it’s a CSR project?

Melaka3.com is a non-profit website to promote Melaka as a tourism spot, we share travel-related information and review interesting places around Melaka that we have personally visited. We thought that this is an interesting project to work-on given all of us been staying here for at least few years and each have some special places or recommendations to share (it’s a good excuse to explore Melaka too). :P We believe we could help promote Melaka as a must stop place for tourist travelling to Malaysia (a lil’ Melakanism here :D), and we believe we can do this efficiently given the IT expertise available in the company (which i soon found that we need more than IT expertise, for example, we need designer and marketing talents. :( Well, let’s deal with this later).

These are what we have done so far:

  1. Melaka3 home page – www.melaka3.com 
  2. Melaka3 social medias:
  3. Sponsored JCI IAB 2012 at Dataran Pahlawan Melaka.
  4. Discovered and review a cafe with lots of good feedback from our followers.
  5. Give away a 2GB DDR3 Ram to our Facebook follower (a second hand RAM we got after upgrading some of the laptop in the company) via a simple competition.
  6. Sponsored to students to participate in a beauty contest.
  7. Made 71 blog posts (yup, we know our blog posts are not in good quality but we are working on this. yes, please trust me, we notice.)
  8. Sending out weekly newsletter to our subscribers about the latest happening and promotions in Melaka.

I personally hope this baby will grow and help contribute to Melaka tourism. Kudos to the dedicated and talented who help setup and running this project; they are Edwin, Teck Chia, Shin (aka Monkey), YS Hon, Sang Heng, Jaclyn, Matthew, Yeishyan, and Tian Lee. And thanks to our followers.

Read More

JMC Excel Split – Split excel worksheets into separate workbooks.

Microsoft-Excel-icon This tool helps splitting multiple excel sheets and save each of them as an independent file. It was created following a feature request in another tool that I created - JMC Excel.

If you have many excel sheets created in multiple excel files and wanted to save each of them separately as workbook (or independent .xlsx file), JMC Excel Split will come in very handy.

Below is the download link to the trial version (which can split up to 5 files and 5 sheets each).

JMC Excel Split Download Link

 

 

Want to thank me? Buy me a coffee. Paypal Donation of any amount is welcome. 

Remove limitation by Buying JMC Excel Split at USD 7 only. Contact jeeshenlee@gmail.com.

paypal-logo

Read More

How to update value of LINQ results using FOREACH loop

LINQ queries are lazy loading – that means execution of reading is delayed until it’s iterated. Once set in the LINQ Select statement, the value stored in the result are set as READ ONLY hence setting the value in a FOREACH loop will not really update its data.

For example:

1 var schedules = from roomRate in _entities.RoomRates
2 select new ScheduleViewModel
3 {
4 RoomTypeId = roomRate.RoomTypeId,
5 Rates = roomRate.Rates,
6 Selling = 0,
7 Booked = 0,
8 };
9 foreach (var schedule in schedules)
10 {
11 schedule.Booked = 1;
12 schedule.Selling = 1;
13 }
Variable ‘Schedules’ field Booked and Selling  are not updated even after the FOREACH Loop.

To update the LINQ result using FOREACH loop, I first create local ‘list’ variable and then perform the update using FOREACH Loop. The value are updated this way. The example code below exemplify my idea and i further cast it back to IQueryable :)


Hotelebuddy



1 public IQueryable<ScheduleViewModel> GetScheduleForHotelBetween(int hotelId, DateTime startDate, DateTime endDate)
2 {
3 var schedules = from roomRate in _entities.RoomRates
4 join ratesTypeEnforceDate in _entities.RatesTypeEnforceDates on roomRate.RatesTypeId equals
5 ratesTypeEnforceDate.RatesTypeId
6 where roomRate.RoomType.HotelId == hotelId &&
7 ratesTypeEnforceDate.EnforceDate <= endDate &&
8 ratesTypeEnforceDate.EnforceDate >= startDate
9 select new ScheduleViewModel
10 {
11 RatesType = ratesTypeEnforceDate.RatesType.Name,
12 Date = ratesTypeEnforceDate.EnforceDate,
13 RoomTypeId = roomRate.RoomTypeId,
14 Rates = roomRate.Rates,
15 Selling = 0,
16 Booked = 0,
17 };
18 var schedulesList = new List<ScheduleViewModel>(schedules.AsEnumerable().ToList());
19 foreach (var schedule in schedulesList)
20 {
21 schedule.Booked = BookingDetails.GetBookingCountForRoomTypeOn(schedule.RoomTypeId,
22 schedule.Date);
23 schedule.Selling = RoomForSales.GetRoomForSalesCountForRoomTypeOn(schedule.RoomTypeId,
24 schedule.Date);
25 }
26
27 return (IQueryable<ScheduleViewModel>) schedulesList.AsQueryable();
28 }

Read More

Develop web app on Azure using MVC3 + EntityFramework Database First.

Cloud-icon I was following this tutorial (.NET Web Application with SQL Azure) on Windows Azure website and realised that the tutorial were written using Entity Framework Code First approach. If you are like me - prefer Entity Framework Database First approach, below is the Entity Framework Database First version.

In this post, I will skip the details of the first few steps (setup Azure development environment, create MVC3 app, and Azure enable the app) and go straight to the Database part. You may refer to the article for the step by step guide and come back later for the Database implementation using Entity Framework Database First approach.

 

Azure + MVC3 + Entity Framework Database First Approach

1. Install Windows Azure SDK and setup development environment on Visual Studio.

2. Create ASP.NET MVC3 application.

3. Azure enable your ASP.NET MVC3 application.

4. Add new Database to our app. Right click on App_Data folder and select Add > New Item. Choose SQL Server Database and name it ToDoList.mdf.

AddDatabase

5. Double click on the created database (ToDoList) to add ToDoItem table to the database. Right click on Tables > Add New Table.

AddTable

6. Edit database table to include  these fields – Id, Name, IsComplete. Make sure you set the Id field as primary key and set the Identity Specification. Hit Save button and enter “ToDoItem” as the database table name.

AddDatabaseTable

7. Add data model. Right click on “Model” in the solution explorer and then Add New Item > ADO.NET Entity Data Model >  name it “ToDoListModel.edmx”. Choose "Generate from Database” option. Select “ToDoList.mdf” connection string. Click “Next”.

DatabaseConnectionString

8. Choose to include “ToDoItem” database object.

ChooseDatabaseItem

9. Create Repository Class for ToDoItem to refactor all the data access logic on ToDoItem table. You may refer to this article on why Repository Pattern is good for data access  logic implementation. Basically, Repository Pattern refactor all the data access logic to one class so it’s easier to maintain and test. Right click on Models > Add > Class > ToDoItemRepository.cs. Below is the complete implementation of my ToDoItemRepository class.

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
 
namespace ToDoListApp.Models
{
    public class ToDoItemRepository
    {
        private readonly ToDoListEntities _entities = new ToDoListEntities();
 
 
        //
        // Query Methods
 
        public ToDoItem GetTDI(int id)
        {
            return (from tdi in _entities.ToDoItems
                    where tdi.Id == id
                    select tdi).FirstOrDefault();
        }
 
        public IQueryable<ToDoItem> GetAllToDoItems()
        {
            return from tdi in _entities.ToDoItems
                   select tdi;
        }
 
 
        //
        // Update/Add/Delete Methods
 
        public void Update(ToDoItem tdi)
        {
            _entities.ToDoItems.Attach(tdi);
            _entities.ObjectStateManager.ChangeObjectState(tdi, EntityState.Modified);
        }
 
        public void Add(ToDoItem tdi)
        {
            _entities.ToDoItems.AddObject(tdi);
        }
 
        public void Delete(ToDoItem tdi)
        {
            _entities.ToDoItems.DeleteObject(tdi);
        }
 
 
        //
        // Save
 
        public void Save()
        {
            _entities.SaveChanges();
        }
 
 
        // Dispose
 
        public void Dispose()
        {
            _entities.Dispose();
        }
    }
}





10. Recreate the HomeController to show all the ToDoItems. Right click on Controllers > Add > Controller > HomeController.cs.


AddHomeController


AddHomeControllerDetails


11. Modify the generated HomeController.cs to use Repository class.


using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ToDoListApp.Models;
 
namespace ToDoListApp.Controllers
{ 
    public class HomeController : Controller
    {
        private readonly ToDoItemRepository _tdiRepository = new ToDoItemRepository();
 
        //
        // GET: /Home/
 
        public ViewResult Index()
        {
            var tdis = _tdiRepository.GetAllToDoItems();
            return View(tdis.ToList());
        }
 
        //
        // GET: /Home/Details/5
 
        public ViewResult Details(int id)
        {
            var todoitem = _tdiRepository.GetTDI(id);
            return View(todoitem);
        }
 
        //
        // GET: /Home/Create
 
        public ActionResult Create()
        {
            return View();
        } 
 
        //
        // POST: /Home/Create
 
        [HttpPost]
        public ActionResult Create(ToDoItem todoitem)
        {
            if (ModelState.IsValid)
            {
                _tdiRepository.Add(todoitem);
                _tdiRepository.Save();
                return RedirectToAction("Index");  
            }
 
            return View(todoitem);
        }
        
        //
        // GET: /Home/Edit/5
 
        public ActionResult Edit(int id)
        {
            var todoitem = _tdiRepository.GetTDI(id);
            return View(todoitem);
        }
 
        //
        // POST: /Home/Edit/5
 
        [HttpPost]
        public ActionResult Edit(ToDoItem todoitem)
        {
            if (ModelState.IsValid)
            {
                _tdiRepository.Update(todoitem);
                _tdiRepository.Save();
                return RedirectToAction("Index");
            }
            return View(todoitem);
        }
 
        //
        // GET: /Home/Delete/5
 
        public ActionResult Delete(int id)
        {
            var todoitem = _tdiRepository.GetTDI(id);
            return View(todoitem);
        }
 
        //
        // POST: /Home/Delete/5
 
        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            var todoitem = _tdiRepository.GetTDI(id);
            _tdiRepository.Delete(todoitem);
            _tdiRepository.Save();
            return RedirectToAction("Index");
        }
 
        protected override void Dispose(bool disposing)
        {
            _tdiRepository.Dispose();
            base.Dispose(disposing);
        }
    }
}

12. Login to https://windows.azure.com/. Add SQL Database on Azure. Database > Subscription > Create > Choose Server Region > Key in username and password >


AddSQLDatabaseOnAzure

Read More